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 extern struct kmem_cache *fanotify_mnt_event_cachep; 13 14 /* Possible states of the permission event */ 15 enum { 16 FAN_EVENT_INIT, 17 FAN_EVENT_REPORTED, 18 FAN_EVENT_ANSWERED, 19 FAN_EVENT_CANCELED, 20 }; 21 22 /* 23 * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation). 24 * fh buf should be dword aligned. On 64bit arch, the ext_buf pointer is 25 * stored in either the first or last 2 dwords. 26 */ 27 #define FANOTIFY_INLINE_FH_LEN (3 << 2) 28 #define FANOTIFY_FH_HDR_LEN sizeof(struct fanotify_fh) 29 30 /* Fixed size struct for file handle */ 31 struct fanotify_fh { 32 u8 type; 33 u8 len; 34 #define FANOTIFY_FH_FLAG_EXT_BUF 1 35 u8 flags; 36 u8 pad; 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 dir2_fh_totlen; 44 u8 file_fh_totlen; 45 u8 name_len; 46 u8 name2_len; 47 u8 pad[3]; 48 unsigned char buf[]; 49 /* 50 * (struct fanotify_fh) dir_fh starts at buf[0] 51 * (optional) dir2_fh starts at buf[dir_fh_totlen] 52 * (optional) file_fh starts at buf[dir_fh_totlen + dir2_fh_totlen] 53 * name starts at buf[dir_fh_totlen + dir2_fh_totlen + file_fh_totlen] 54 * ... 55 */ 56 #define FANOTIFY_DIR_FH_SIZE(info) ((info)->dir_fh_totlen) 57 #define FANOTIFY_DIR2_FH_SIZE(info) ((info)->dir2_fh_totlen) 58 #define FANOTIFY_FILE_FH_SIZE(info) ((info)->file_fh_totlen) 59 #define FANOTIFY_NAME_SIZE(info) ((info)->name_len + 1) 60 #define FANOTIFY_NAME2_SIZE(info) ((info)->name2_len + 1) 61 62 #define FANOTIFY_DIR_FH_OFFSET(info) 0 63 #define FANOTIFY_DIR2_FH_OFFSET(info) \ 64 (FANOTIFY_DIR_FH_OFFSET(info) + FANOTIFY_DIR_FH_SIZE(info)) 65 #define FANOTIFY_FILE_FH_OFFSET(info) \ 66 (FANOTIFY_DIR2_FH_OFFSET(info) + FANOTIFY_DIR2_FH_SIZE(info)) 67 #define FANOTIFY_NAME_OFFSET(info) \ 68 (FANOTIFY_FILE_FH_OFFSET(info) + FANOTIFY_FILE_FH_SIZE(info)) 69 #define FANOTIFY_NAME2_OFFSET(info) \ 70 (FANOTIFY_NAME_OFFSET(info) + FANOTIFY_NAME_SIZE(info)) 71 72 #define FANOTIFY_DIR_FH_BUF(info) \ 73 ((info)->buf + FANOTIFY_DIR_FH_OFFSET(info)) 74 #define FANOTIFY_DIR2_FH_BUF(info) \ 75 ((info)->buf + FANOTIFY_DIR2_FH_OFFSET(info)) 76 #define FANOTIFY_FILE_FH_BUF(info) \ 77 ((info)->buf + FANOTIFY_FILE_FH_OFFSET(info)) 78 #define FANOTIFY_NAME_BUF(info) \ 79 ((info)->buf + FANOTIFY_NAME_OFFSET(info)) 80 #define FANOTIFY_NAME2_BUF(info) \ 81 ((info)->buf + FANOTIFY_NAME2_OFFSET(info)) 82 } __aligned(4); 83 84 static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) 85 { 86 return (fh->flags & FANOTIFY_FH_FLAG_EXT_BUF); 87 } 88 89 static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh) 90 { 91 BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN % 4); 92 BUILD_BUG_ON(__alignof__(char *) - 4 + sizeof(char *) > 93 FANOTIFY_INLINE_FH_LEN); 94 return (char **)ALIGN((unsigned long)(fh + 1), __alignof__(char *)); 95 } 96 97 static inline void *fanotify_fh_ext_buf(struct fanotify_fh *fh) 98 { 99 return *fanotify_fh_ext_buf_ptr(fh); 100 } 101 102 static inline void *fanotify_fh_buf(struct fanotify_fh *fh) 103 { 104 return fanotify_fh_has_ext_buf(fh) ? fanotify_fh_ext_buf(fh) : fh + 1; 105 } 106 107 static inline int fanotify_info_dir_fh_len(struct fanotify_info *info) 108 { 109 if (!info->dir_fh_totlen || 110 WARN_ON_ONCE(info->dir_fh_totlen < FANOTIFY_FH_HDR_LEN)) 111 return 0; 112 113 return info->dir_fh_totlen - FANOTIFY_FH_HDR_LEN; 114 } 115 116 static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *info) 117 { 118 BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4); 119 120 return (struct fanotify_fh *)FANOTIFY_DIR_FH_BUF(info); 121 } 122 123 static inline int fanotify_info_dir2_fh_len(struct fanotify_info *info) 124 { 125 if (!info->dir2_fh_totlen || 126 WARN_ON_ONCE(info->dir2_fh_totlen < FANOTIFY_FH_HDR_LEN)) 127 return 0; 128 129 return info->dir2_fh_totlen - FANOTIFY_FH_HDR_LEN; 130 } 131 132 static inline struct fanotify_fh *fanotify_info_dir2_fh(struct fanotify_info *info) 133 { 134 return (struct fanotify_fh *)FANOTIFY_DIR2_FH_BUF(info); 135 } 136 137 static inline int fanotify_info_file_fh_len(struct fanotify_info *info) 138 { 139 if (!info->file_fh_totlen || 140 WARN_ON_ONCE(info->file_fh_totlen < FANOTIFY_FH_HDR_LEN)) 141 return 0; 142 143 return info->file_fh_totlen - FANOTIFY_FH_HDR_LEN; 144 } 145 146 static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info) 147 { 148 return (struct fanotify_fh *)FANOTIFY_FILE_FH_BUF(info); 149 } 150 151 static inline char *fanotify_info_name(struct fanotify_info *info) 152 { 153 if (!info->name_len) 154 return NULL; 155 156 return FANOTIFY_NAME_BUF(info); 157 } 158 159 static inline char *fanotify_info_name2(struct fanotify_info *info) 160 { 161 if (!info->name2_len) 162 return NULL; 163 164 return FANOTIFY_NAME2_BUF(info); 165 } 166 167 static inline void fanotify_info_init(struct fanotify_info *info) 168 { 169 BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN + MAX_HANDLE_SZ > U8_MAX); 170 BUILD_BUG_ON(NAME_MAX > U8_MAX); 171 172 info->dir_fh_totlen = 0; 173 info->dir2_fh_totlen = 0; 174 info->file_fh_totlen = 0; 175 info->name_len = 0; 176 info->name2_len = 0; 177 } 178 179 /* These set/copy helpers MUST be called by order */ 180 static inline void fanotify_info_set_dir_fh(struct fanotify_info *info, 181 unsigned int totlen) 182 { 183 if (WARN_ON_ONCE(info->dir2_fh_totlen > 0) || 184 WARN_ON_ONCE(info->file_fh_totlen > 0) || 185 WARN_ON_ONCE(info->name_len > 0) || 186 WARN_ON_ONCE(info->name2_len > 0)) 187 return; 188 189 info->dir_fh_totlen = totlen; 190 } 191 192 static inline void fanotify_info_set_dir2_fh(struct fanotify_info *info, 193 unsigned int totlen) 194 { 195 if (WARN_ON_ONCE(info->file_fh_totlen > 0) || 196 WARN_ON_ONCE(info->name_len > 0) || 197 WARN_ON_ONCE(info->name2_len > 0)) 198 return; 199 200 info->dir2_fh_totlen = totlen; 201 } 202 203 static inline void fanotify_info_set_file_fh(struct fanotify_info *info, 204 unsigned int totlen) 205 { 206 if (WARN_ON_ONCE(info->name_len > 0) || 207 WARN_ON_ONCE(info->name2_len > 0)) 208 return; 209 210 info->file_fh_totlen = totlen; 211 } 212 213 static inline void fanotify_info_copy_name(struct fanotify_info *info, 214 const struct qstr *name) 215 { 216 if (WARN_ON_ONCE(name->len > NAME_MAX) || 217 WARN_ON_ONCE(info->name2_len > 0)) 218 return; 219 220 info->name_len = name->len; 221 strcpy(fanotify_info_name(info), name->name); 222 } 223 224 static inline void fanotify_info_copy_name2(struct fanotify_info *info, 225 const struct qstr *name) 226 { 227 if (WARN_ON_ONCE(name->len > NAME_MAX)) 228 return; 229 230 info->name2_len = name->len; 231 strcpy(fanotify_info_name2(info), name->name); 232 } 233 234 /* 235 * Common structure for fanotify events. Concrete structs are allocated in 236 * fanotify_handle_event() and freed when the information is retrieved by 237 * userspace. The type of event determines how it was allocated, how it will 238 * be freed and which concrete struct it may be cast to. 239 */ 240 enum fanotify_event_type { 241 FANOTIFY_EVENT_TYPE_FID, /* fixed length */ 242 FANOTIFY_EVENT_TYPE_FID_NAME, /* variable length */ 243 FANOTIFY_EVENT_TYPE_PATH, 244 FANOTIFY_EVENT_TYPE_PATH_PERM, 245 FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */ 246 FANOTIFY_EVENT_TYPE_FS_ERROR, /* struct fanotify_error_event */ 247 FANOTIFY_EVENT_TYPE_MNT, 248 __FANOTIFY_EVENT_TYPE_NUM 249 }; 250 251 #define FANOTIFY_EVENT_TYPE_BITS \ 252 (ilog2(__FANOTIFY_EVENT_TYPE_NUM - 1) + 1) 253 #define FANOTIFY_EVENT_HASH_BITS \ 254 (32 - FANOTIFY_EVENT_TYPE_BITS) 255 256 struct fanotify_event { 257 struct fsnotify_event fse; 258 struct hlist_node merge_list; /* List for hashed merge */ 259 u32 mask; 260 struct { 261 unsigned int type : FANOTIFY_EVENT_TYPE_BITS; 262 unsigned int hash : FANOTIFY_EVENT_HASH_BITS; 263 }; 264 struct pid *pid; 265 }; 266 267 static inline void fanotify_init_event(struct fanotify_event *event, 268 unsigned int hash, u32 mask) 269 { 270 fsnotify_init_event(&event->fse); 271 INIT_HLIST_NODE(&event->merge_list); 272 event->hash = hash; 273 event->mask = mask; 274 event->pid = NULL; 275 } 276 277 #define FANOTIFY_INLINE_FH(name, size) \ 278 struct { \ 279 struct fanotify_fh name; \ 280 /* Space for filehandle - access with fanotify_fh_buf() */ \ 281 unsigned char _inline_fh_buf[size]; \ 282 } 283 284 struct fanotify_fid_event { 285 struct fanotify_event fae; 286 __kernel_fsid_t fsid; 287 288 FANOTIFY_INLINE_FH(object_fh, FANOTIFY_INLINE_FH_LEN); 289 }; 290 291 static inline struct fanotify_fid_event * 292 FANOTIFY_FE(struct fanotify_event *event) 293 { 294 return container_of(event, struct fanotify_fid_event, fae); 295 } 296 297 struct fanotify_name_event { 298 struct fanotify_event fae; 299 __kernel_fsid_t fsid; 300 struct fanotify_info info; 301 }; 302 303 static inline struct fanotify_name_event * 304 FANOTIFY_NE(struct fanotify_event *event) 305 { 306 return container_of(event, struct fanotify_name_event, fae); 307 } 308 309 struct fanotify_error_event { 310 struct fanotify_event fae; 311 s32 error; /* Error reported by the Filesystem. */ 312 u32 err_count; /* Suppressed errors count */ 313 314 __kernel_fsid_t fsid; /* FSID this error refers to. */ 315 316 FANOTIFY_INLINE_FH(object_fh, MAX_HANDLE_SZ); 317 }; 318 319 static inline struct fanotify_error_event * 320 FANOTIFY_EE(struct fanotify_event *event) 321 { 322 return container_of(event, struct fanotify_error_event, fae); 323 } 324 325 static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event) 326 { 327 if (event->type == FANOTIFY_EVENT_TYPE_FID) 328 return &FANOTIFY_FE(event)->fsid; 329 else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 330 return &FANOTIFY_NE(event)->fsid; 331 else if (event->type == FANOTIFY_EVENT_TYPE_FS_ERROR) 332 return &FANOTIFY_EE(event)->fsid; 333 else 334 return NULL; 335 } 336 337 static inline struct fanotify_fh *fanotify_event_object_fh( 338 struct fanotify_event *event) 339 { 340 if (event->type == FANOTIFY_EVENT_TYPE_FID) 341 return &FANOTIFY_FE(event)->object_fh; 342 else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 343 return fanotify_info_file_fh(&FANOTIFY_NE(event)->info); 344 else if (event->type == FANOTIFY_EVENT_TYPE_FS_ERROR) 345 return &FANOTIFY_EE(event)->object_fh; 346 else 347 return NULL; 348 } 349 350 static inline struct fanotify_info *fanotify_event_info( 351 struct fanotify_event *event) 352 { 353 if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) 354 return &FANOTIFY_NE(event)->info; 355 else 356 return NULL; 357 } 358 359 static inline int fanotify_event_object_fh_len(struct fanotify_event *event) 360 { 361 struct fanotify_info *info = fanotify_event_info(event); 362 struct fanotify_fh *fh = fanotify_event_object_fh(event); 363 364 if (info) 365 return info->file_fh_totlen ? fh->len : 0; 366 else 367 return fh ? fh->len : 0; 368 } 369 370 static inline int fanotify_event_dir_fh_len(struct fanotify_event *event) 371 { 372 struct fanotify_info *info = fanotify_event_info(event); 373 374 return info ? fanotify_info_dir_fh_len(info) : 0; 375 } 376 377 static inline int fanotify_event_dir2_fh_len(struct fanotify_event *event) 378 { 379 struct fanotify_info *info = fanotify_event_info(event); 380 381 return info ? fanotify_info_dir2_fh_len(info) : 0; 382 } 383 384 static inline bool fanotify_event_has_object_fh(struct fanotify_event *event) 385 { 386 /* For error events, even zeroed fh are reported. */ 387 if (event->type == FANOTIFY_EVENT_TYPE_FS_ERROR) 388 return true; 389 return fanotify_event_object_fh_len(event) > 0; 390 } 391 392 static inline bool fanotify_event_has_dir_fh(struct fanotify_event *event) 393 { 394 return fanotify_event_dir_fh_len(event) > 0; 395 } 396 397 static inline bool fanotify_event_has_dir2_fh(struct fanotify_event *event) 398 { 399 return fanotify_event_dir2_fh_len(event) > 0; 400 } 401 402 static inline bool fanotify_event_has_any_dir_fh(struct fanotify_event *event) 403 { 404 return fanotify_event_has_dir_fh(event) || 405 fanotify_event_has_dir2_fh(event); 406 } 407 408 struct fanotify_path_event { 409 struct fanotify_event fae; 410 struct path path; 411 }; 412 413 struct fanotify_mnt_event { 414 struct fanotify_event fae; 415 u64 mnt_id; 416 }; 417 418 static inline struct fanotify_path_event * 419 FANOTIFY_PE(struct fanotify_event *event) 420 { 421 return container_of(event, struct fanotify_path_event, fae); 422 } 423 424 static inline struct fanotify_mnt_event * 425 FANOTIFY_ME(struct fanotify_event *event) 426 { 427 return container_of(event, struct fanotify_mnt_event, fae); 428 } 429 430 /* 431 * Structure for permission fanotify events. It gets allocated and freed in 432 * fanotify_handle_event() since we wait there for user response. When the 433 * information is retrieved by userspace the structure is moved from 434 * group->notification_list to group->fanotify_data.access_list to wait for 435 * user response. 436 */ 437 struct fanotify_perm_event { 438 struct fanotify_event fae; 439 struct path path; 440 const loff_t *ppos; /* optional file range info */ 441 size_t count; 442 u32 response; /* userspace answer to the event */ 443 unsigned short state; /* state of the event */ 444 int fd; /* fd we passed to userspace for this event */ 445 union { 446 struct fanotify_response_info_header hdr; 447 struct fanotify_response_info_audit_rule audit_rule; 448 }; 449 }; 450 451 static inline struct fanotify_perm_event * 452 FANOTIFY_PERM(struct fanotify_event *event) 453 { 454 return container_of(event, struct fanotify_perm_event, fae); 455 } 456 457 static inline bool fanotify_is_perm_event(u32 mask) 458 { 459 return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) && 460 mask & FANOTIFY_PERM_EVENTS; 461 } 462 463 static inline bool fanotify_event_has_access_range(struct fanotify_event *event) 464 { 465 if (!(event->mask & FANOTIFY_PRE_CONTENT_EVENTS)) 466 return false; 467 468 return FANOTIFY_PERM(event)->ppos; 469 } 470 471 static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse) 472 { 473 return container_of(fse, struct fanotify_event, fse); 474 } 475 476 static inline bool fanotify_is_error_event(u32 mask) 477 { 478 return mask & FAN_FS_ERROR; 479 } 480 481 static inline bool fanotify_is_mnt_event(u32 mask) 482 { 483 return mask & (FAN_MNT_ATTACH | FAN_MNT_DETACH); 484 } 485 486 static inline const struct path *fanotify_event_path(struct fanotify_event *event) 487 { 488 if (event->type == FANOTIFY_EVENT_TYPE_PATH) 489 return &FANOTIFY_PE(event)->path; 490 else if (event->type == FANOTIFY_EVENT_TYPE_PATH_PERM) 491 return &FANOTIFY_PERM(event)->path; 492 else 493 return NULL; 494 } 495 496 /* 497 * Use 128 size hash table to speed up events merge. 498 */ 499 #define FANOTIFY_HTABLE_BITS (7) 500 #define FANOTIFY_HTABLE_SIZE (1 << FANOTIFY_HTABLE_BITS) 501 #define FANOTIFY_HTABLE_MASK (FANOTIFY_HTABLE_SIZE - 1) 502 503 /* 504 * Permission events and overflow event do not get merged - don't hash them. 505 */ 506 static inline bool fanotify_is_hashed_event(u32 mask) 507 { 508 return !(fanotify_is_perm_event(mask) || 509 fsnotify_is_overflow_event(mask)); 510 } 511 512 static inline unsigned int fanotify_event_hash_bucket( 513 struct fsnotify_group *group, 514 struct fanotify_event *event) 515 { 516 return event->hash & FANOTIFY_HTABLE_MASK; 517 } 518 519 struct fanotify_mark { 520 struct fsnotify_mark fsn_mark; 521 __kernel_fsid_t fsid; 522 }; 523 524 static inline struct fanotify_mark *FANOTIFY_MARK(struct fsnotify_mark *mark) 525 { 526 return container_of(mark, struct fanotify_mark, fsn_mark); 527 } 528 529 static inline bool fanotify_fsid_equal(__kernel_fsid_t *fsid1, 530 __kernel_fsid_t *fsid2) 531 { 532 return fsid1->val[0] == fsid2->val[0] && fsid1->val[1] == fsid2->val[1]; 533 } 534 535 static inline unsigned int fanotify_mark_user_flags(struct fsnotify_mark *mark) 536 { 537 unsigned int mflags = 0; 538 539 if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY) 540 mflags |= FAN_MARK_IGNORED_SURV_MODIFY; 541 if (mark->flags & FSNOTIFY_MARK_FLAG_NO_IREF) 542 mflags |= FAN_MARK_EVICTABLE; 543 if (mark->flags & FSNOTIFY_MARK_FLAG_HAS_IGNORE_FLAGS) 544 mflags |= FAN_MARK_IGNORE; 545 546 return mflags; 547 } 548 549 static inline u32 fanotify_get_response_errno(int res) 550 { 551 return (res >> FAN_ERRNO_SHIFT) & FAN_ERRNO_MASK; 552 } 553