fanotify mark add/remove code jumps through hoops to avoid setting the FS_ISDIR in the commulative object mask. That was just papering over a bug in fsnotify() handling of the FS_ISDIR extra flag. This bug is now fixed, so all the hoops can be removed along with the unneeded internal flag FAN_MARK_ONDIR.
Unified · Split
| @@ -506,18 +506,10 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, · 505 unmodified lines | ||
| 506 | 506 | |
| 507 | 507 | spin_lock(&fsn_mark->lock); |
| 508 | 508 | if (!(flags & FAN_MARK_IGNORED_MASK)) { |
| 509 | − __u32 tmask = fsn_mark->mask & ~mask; | |
| 510 | − | |
| 511 | − if (flags & FAN_MARK_ONDIR) | |
| 512 | − tmask &= ~FAN_ONDIR; | |
| 513 | − | |
| 514 | 509 | oldmask = fsn_mark->mask; |
| 515 | − fsn_mark->mask = tmask; | |
| 510 | + fsn_mark->mask &= ~mask; | |
| 516 | 511 | } else { |
| 517 | − __u32 tmask = fsn_mark->ignored_mask & ~mask; | |
| 518 | − if (flags & FAN_MARK_ONDIR) | |
| 519 | − tmask &= ~FAN_ONDIR; | |
| 520 | − fsn_mark->ignored_mask = tmask; | |
| 512 | + fsn_mark->ignored_mask &= ~mask; | |
| 521 | 513 | } |
| 522 | 514 | *destroy = !(fsn_mark->mask | fsn_mark->ignored_mask); |
| 523 | 515 | spin_unlock(&fsn_mark->lock); |
| @@ -586,19 +578,10 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, · 62 unmodified lines | ||
| 586 | 578 | |
| 587 | 579 | spin_lock(&fsn_mark->lock); |
| 588 | 580 | if (!(flags & FAN_MARK_IGNORED_MASK)) { |
| 589 | − __u32 tmask = fsn_mark->mask | mask; | |
| 590 | − | |
| 591 | − if (flags & FAN_MARK_ONDIR) | |
| 592 | − tmask |= FAN_ONDIR; | |
| 593 | − | |
| 594 | 581 | oldmask = fsn_mark->mask; |
| 595 | − fsn_mark->mask = tmask; | |
| 582 | + fsn_mark->mask |= mask; | |
| 596 | 583 | } else { |
| 597 | − __u32 tmask = fsn_mark->ignored_mask | mask; | |
| 598 | − if (flags & FAN_MARK_ONDIR) | |
| 599 | − tmask |= FAN_ONDIR; | |
| 600 | − | |
| 601 | − fsn_mark->ignored_mask = tmask; | |
| 584 | + fsn_mark->ignored_mask |= mask; | |
| 602 | 585 | if (flags & FAN_MARK_IGNORED_SURV_MODIFY) |
| 603 | 586 | fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; |
| 604 | 587 | } |
| @@ -820,7 +803,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, · 215 unmodified lines | ||
| 820 | 803 | struct fsnotify_group *group; |
| 821 | 804 | struct fd f; |
| 822 | 805 | struct path path; |
| 823 | − u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD; | |
| 806 | + u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD | FAN_ONDIR; | |
| 824 | 807 | unsigned int mark_type = flags & FAN_MARK_TYPE_MASK; |
| 825 | 808 | int ret; |
| 826 | 809 | |
| @@ -857,11 +840,6 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, · 30 unmodified lines | ||
| 857 | 840 | return -EINVAL; |
| 858 | 841 | } |
| 859 | 842 | |
| 860 | − if (mask & FAN_ONDIR) { | |
| 861 | − flags |= FAN_MARK_ONDIR; | |
| 862 | − mask &= ~FAN_ONDIR; | |
| 863 | − } | |
| 864 | − | |
| 865 | 843 | if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) |
| 866 | 844 | valid_mask |= FAN_ALL_PERM_EVENTS; |
| 867 | 845 | |
| @@ -4,9 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <uapi/linux/fanotify.h> |
| 6 | 6 | |
| 7 | −/* not valid from userspace, only kernel internal */ | |
| 8 | −#define FAN_MARK_ONDIR 0x80000000 | |
| 9 | − | |
| 10 | 7 | #define FAN_GROUP_FLAG(group, flag) \ |
| 11 | 8 | ((group)->fanotify_data.flags & (flag)) |
| 12 | 9 | |