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