1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/fsnotify_backend.h> 3 #include <linux/path.h> 4 #include <linux/slab.h> 5 #include <linux/exportfs.h> 6 #include <linux/hashtable.h> 7 8 extern struct kmem_cache *fanotify_mark_cache; 9 extern struct kmem_cache *fanotify_fid_event_cachep; 10 extern struct kmem_cache *fanotify_path_event_cachep; 11 extern struct kmem_cache *fanotify_perm_event_cachep; 12 13 /* Possible states of the permission event */ 14 enum { 15 FAN_EVENT_INIT, 16 FAN_EVENT_REPORTED, 17 FAN_EVENT_ANSWERED, 18 FAN_EVENT_CANCELED, 19 }; 20 21 /* 22 * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation). 23 * fh buf should be dword aligned. On 64bit arch, the ext_buf pointer is 24 * stored in either the first or last 2 dwords. 25 */ 26 #define FANOTIFY_INLINE_FH_LEN (3 << 2) 27 #define FANOTIFY_FH_HDR_LEN offsetof(struct fanotify_fh, buf) 28 29 /* Fixed size struct for file handle */ 30 struct fanotify_fh { 31 u8 type; 32 u8 len; 33 #define FANOTIFY_FH_FLAG_EXT_BUF 1 34 u8 flags; 35 u8 pad; 36 unsigned char buf[]; 37 } __aligned(4); 38 39 /* Variable size struct for dir file handle + child file handle + name */ 40 struct fanotify_info { 41 /* size of dir_fh/file_fh including fanotify_fh hdr size */ 42 u8 dir_fh_totlen; 43 u8 file_fh_totlen; 44 u8 name_len; 45 u8 pad; 46 unsigned char buf[]; 47 /* 48 * (struct fanotify_fh) dir_fh starts at buf[0] 49 * (optional) file_fh starts at buf[dir_fh_totlen] 50 * name starts at buf[dir_fh_totlen + file_fh_totlen] 51 */ 52 } __aligned(4); 53 54 static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) 55 { 56 return (fh->flags & FANOTIFY_FH_FLAG_EXT_BUF); 57 } 58 59 static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh) 60 { 61 BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN % 4); 62 BUILD_BUG_ON(__alignof__(char *) - 4 + sizeof(char *) > 63 FANOTIFY_INLINE_FH_LEN); 64 return (char **)ALIGN((unsigned long)(fh->buf), __alignof__(char *)); 65 } 66 67 static inline void *fanotify_fh_ext_buf(struct fanotify_fh *fh) 68 { 69 return *fanotify_fh_ext_buf_ptr(fh); 70 } 71 72 static inline void *fanotify_fh_buf(struct fanotify_fh *fh) 73 { 74 return fanotify_fh_has_ext_buf(fh) ? fanotify_fh_ext_buf(fh) : fh->buf; 75 } 76 77 static inline int fanotify_info_dir_fh_len(struct fanotify_info *info) 78 { 79 if (!info->dir_fh_totlen || 80 WARN_ON_ONCE(info->dir_fh_totlen < FANOTIFY_FH_HDR_LEN)) 81 return 0; 82 83 return info->dir_fh_totlen - FANOTIFY_FH_HDR_LEN; 84 } 85 86 static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *info) 87 { 88 BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4); 89 90 return (struct fanotify_fh *)info->buf; 91 } 92 93 static inline int fanotify_info_file_fh_len(struct fanotify_info *info) 94 { 95 if (!info->file_fh_totlen || 96 WARN_ON_ONCE(info->file_fh_totlen < FANOTIFY_FH_HDR_LEN)) 97 return 0; 98 99 return info->file_fh_totlen - FANOTIFY_FH_HDR_LEN; 100 } 101 102 static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info) 103 { 104 return (struct fanotify_fh *)(info->buf + info->dir_fh_totlen); 105 } 106 107 static inline const char *fanotify_info_name(struct fanotify_info *info) 108 { 109 return info->buf + info->dir_fh_totlen + info->file_fh_totlen; 110 } 111 112 static inline void fanotify_info_init(struct fanotify_info *info) 113 { 114 info->dir_fh_totlen = 0; 115 info->file_fh_totlen = 0; 116 info->name_len = 0; 117 } 118 119 static inline unsigned int fanotify_info_len(struct fanotify_info *info) 120 { 121 return info->dir_fh_totlen + info->file_fh_totlen + info->name_len; 122 } 123 124 static inline void fanotify_info_copy_name(struct fanotify_info *info, 125 const struct qstr *name) 126 { 127 info->name_len = name->len; 128 strcpy(info->buf + info->dir_fh_totlen + info->file_fh_totlen, 129 name->name); 130 } 131 132 /* 133 * Common structure for fanotify events. Concrete structs are allocated in 134 * fanotify_handle_event() and freed when the information is retrieved by 135 * userspace. The type of event determines how it was allocated, how it will 136 * be freed and which concrete struct it may be cast to. 137 */ 138 enum fanotify_event_type { 139 FANOTIFY_EVENT_TYPE_FID, /* fixed length */ 140 FANOTIFY_EVENT_TYPE_FID_NAME, /* variable length */ 141 FANOTIFY_EVENT_TYPE_PATH, 142 FANOTIFY_EVENT_TYPE_PATH_PERM, 143 FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */ 144 __FANOTIFY_EVENT_TYPE_NUM 145 }; 146 147 #define FANOTIFY_EVENT_TYPE_BITS \ 148 (ilog2(__FANOTIFY_EVENT_TYPE_NUM - 1) + 1) 149 #define FANOTIFY_EVENT_HASH_BITS \ 150 (32 - FANOTIFY_EVENT_TYPE_BITS) 151 152 struct fanotify_event { 153 struct fsnotify_event fse; 154 struct hlist_node merge_list; /* List for hashed merge */ 155 u32 mask; 156 struct { 157 unsigned int type : FANOTIFY_EVENT_TYPE_BITS; 158 unsigned int hash : FANOTIFY_EVENT_HASH_BITS; 159 }; 160 struct pid *pid; 161 }; 162 163 static inline void fanotify_init_event(struct fanotify_event *event, 164 unsigned int hash, u32 mask) 165 { 166 fsnotify_init_event(&event->fse); 167 INIT_HLIST_NODE(&event->merge_list); 168 event->hash = hash; 169 event->mask = mask; 170 event->pid = NULL; 171 } 172 173 struct fanotify_fid_event { 174 struct fanotify_event fae; 175 __kernel_fsid_t fsid; 176 struct fanotify_fh object_fh; 177 /* Reserve space in object_fh.buf[] - access with fanotify_fh_buf() */ 178 unsigned char _inline_fh_buf[FANOTIFY_INLINE_FH_LEN]; 179 }; 180 181 static inline struct fanotify_fid_event * 182 FANOTIFY_FE(struct fanotify_event *event) 183 { 184 return container_of(event, struct fanotify_fid_event, fae); 185 } 186 187 struct fanotify_name_event { 188 struct fanotify_event fae; 189 __kernel_fsid_t fsid; 190 struct fanotify_info info; 191 }; 192 193 static inline struct fanotify_name_event * 194 FANOTIFY_NE(struct fanotify_event *event) 195 { 196 return container_of(event, struct fanotify_name_event, fae); 197 } 198 199 static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event) 200 { 201 if (event->type == FANOTIFY_EVENT_TYPE_FID) 202 return &FANOTIFY_FE(event)->fsid; 203 else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 204 return &FANOTIFY_NE(event)->fsid; 205 else 206 return NULL; 207 } 208 209 static inline struct fanotify_fh *fanotify_event_object_fh( 210 struct fanotify_event *event) 211 { 212 if (event->type == FANOTIFY_EVENT_TYPE_FID) 213 return &FANOTIFY_FE(event)->object_fh; 214 else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 215 return fanotify_info_file_fh(&FANOTIFY_NE(event)->info); 216 else 217 return NULL; 218 } 219 220 static inline struct fanotify_info *fanotify_event_info( 221 struct fanotify_event *event) 222 { 223 if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 224 return &FANOTIFY_NE(event)->info; 225 else 226 return NULL; 227 } 228 229 static inline int fanotify_event_object_fh_len(struct fanotify_event *event) 230 { 231 struct fanotify_info *info = fanotify_event_info(event); 232 struct fanotify_fh *fh = fanotify_event_object_fh(event); 233 234 if (info) 235 return info->file_fh_totlen ? fh->len : 0; 236 else 237 return fh ? fh->len : 0; 238 } 239 240 static inline int fanotify_event_dir_fh_len(struct fanotify_event *event) 241 { 242 struct fanotify_info *info = fanotify_event_info(event); 243 244 return info ? fanotify_info_dir_fh_len(info) : 0; 245 } 246 247 struct fanotify_path_event { 248 struct fanotify_event fae; 249 struct path path; 250 }; 251 252 static inline struct fanotify_path_event * 253 FANOTIFY_PE(struct fanotify_event *event) 254 { 255 return container_of(event, struct fanotify_path_event, fae); 256 } 257 258 /* 259 * Structure for permission fanotify events. It gets allocated and freed in 260 * fanotify_handle_event() since we wait there for user response. When the 261 * information is retrieved by userspace the structure is moved from 262 * group->notification_list to group->fanotify_data.access_list to wait for 263 * user response. 264 */ 265 struct fanotify_perm_event { 266 struct fanotify_event fae; 267 struct path path; 268 unsigned short response; /* userspace answer to the event */ 269 unsigned short state; /* state of the event */ 270 int fd; /* fd we passed to userspace for this event */ 271 }; 272 273 static inline struct fanotify_perm_event * 274 FANOTIFY_PERM(struct fanotify_event *event) 275 { 276 return container_of(event, struct fanotify_perm_event, fae); 277 } 278 279 static inline bool fanotify_is_perm_event(u32 mask) 280 { 281 return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) && 282 mask & FANOTIFY_PERM_EVENTS; 283 } 284 285 static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse) 286 { 287 return container_of(fse, struct fanotify_event, fse); 288 } 289 290 static inline bool fanotify_event_has_path(struct fanotify_event *event) 291 { 292 return event->type == FANOTIFY_EVENT_TYPE_PATH || 293 event->type == FANOTIFY_EVENT_TYPE_PATH_PERM; 294 } 295 296 static inline struct path *fanotify_event_path(struct fanotify_event *event) 297 { 298 if (event->type == FANOTIFY_EVENT_TYPE_PATH) 299 return &FANOTIFY_PE(event)->path; 300 else if (event->type == FANOTIFY_EVENT_TYPE_PATH_PERM) 301 return &FANOTIFY_PERM(event)->path; 302 else 303 return NULL; 304 } 305 306 /* 307 * Use 128 size hash table to speed up events merge. 308 */ 309 #define FANOTIFY_HTABLE_BITS (7) 310 #define FANOTIFY_HTABLE_SIZE (1 << FANOTIFY_HTABLE_BITS) 311 #define FANOTIFY_HTABLE_MASK (FANOTIFY_HTABLE_SIZE - 1) 312 313 /* 314 * Permission events and overflow event do not get merged - don't hash them. 315 */ 316 static inline bool fanotify_is_hashed_event(u32 mask) 317 { 318 return !fanotify_is_perm_event(mask) && !(mask & FS_Q_OVERFLOW); 319 } 320 321 static inline unsigned int fanotify_event_hash_bucket( 322 struct fsnotify_group *group, 323 struct fanotify_event *event) 324 { 325 return event->hash & FANOTIFY_HTABLE_MASK; 326 } 327