Skip to content

Commit 8698e3b

Browse files
amir73iljankara
authored andcommitted
fanotify: refine the validation checks on non-dir inode mask
Commit ceaf69f ("fanotify: do not allow setting dirent events in mask of non-dir") added restrictions about setting dirent events in the mask of a non-dir inode mark, which does not make any sense. For backward compatibility, these restictions were added only to new (v5.17+) APIs. It also does not make any sense to set the flags FAN_EVENT_ON_CHILD or FAN_ONDIR in the mask of a non-dir inode. Add these flags to the dir-only restriction of the new APIs as well. Move the check of the dir-only flags for new APIs into the helper fanotify_events_supported(), which is only called for FAN_MARK_ADD, because there is no need to error on an attempt to remove the dir-only flags from non-dir inode. Fixes: ceaf69f ("fanotify: do not allow setting dirent events in mask of non-dir") Link: https://lore.kernel.org/linux-fsdevel/[email protected]/ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent ca1fdab commit 8698e3b

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

fs/notify/fanotify/fanotify_user.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,8 +1513,15 @@ static int fanotify_test_fid(struct dentry *dentry)
15131513
return 0;
15141514
}
15151515

1516-
static int fanotify_events_supported(struct path *path, __u64 mask)
1516+
static int fanotify_events_supported(struct fsnotify_group *group,
1517+
struct path *path, __u64 mask,
1518+
unsigned int flags)
15171519
{
1520+
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
1521+
/* Strict validation of events in non-dir inode mask with v5.17+ APIs */
1522+
bool strict_dir_events = FAN_GROUP_FLAG(group, FAN_REPORT_TARGET_FID) ||
1523+
(mask & FAN_RENAME);
1524+
15181525
/*
15191526
* Some filesystems such as 'proc' acquire unusual locks when opening
15201527
* files. For them fanotify permission events have high chances of
@@ -1526,6 +1533,16 @@ static int fanotify_events_supported(struct path *path, __u64 mask)
15261533
if (mask & FANOTIFY_PERM_EVENTS &&
15271534
path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM)
15281535
return -EINVAL;
1536+
1537+
/*
1538+
* We shouldn't have allowed setting dirent events and the directory
1539+
* flags FAN_ONDIR and FAN_EVENT_ON_CHILD in mask of non-dir inode,
1540+
* but because we always allowed it, error only when using new APIs.
1541+
*/
1542+
if (strict_dir_events && mark_type == FAN_MARK_INODE &&
1543+
!d_is_dir(path->dentry) && (mask & FANOTIFY_DIRONLY_EVENT_BITS))
1544+
return -ENOTDIR;
1545+
15291546
return 0;
15301547
}
15311548

@@ -1672,7 +1689,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
16721689
goto fput_and_out;
16731690

16741691
if (flags & FAN_MARK_ADD) {
1675-
ret = fanotify_events_supported(&path, mask);
1692+
ret = fanotify_events_supported(group, &path, mask, flags);
16761693
if (ret)
16771694
goto path_put_and_out;
16781695
}
@@ -1695,19 +1712,6 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
16951712
else
16961713
mnt = path.mnt;
16971714

1698-
/*
1699-
* FAN_RENAME is not allowed on non-dir (for now).
1700-
* We shouldn't have allowed setting any dirent events in mask of
1701-
* non-dir, but because we always allowed it, error only if group
1702-
* was initialized with the new flag FAN_REPORT_TARGET_FID.
1703-
*/
1704-
ret = -ENOTDIR;
1705-
if (inode && !S_ISDIR(inode->i_mode) &&
1706-
((mask & FAN_RENAME) ||
1707-
((mask & FANOTIFY_DIRENT_EVENTS) &&
1708-
FAN_GROUP_FLAG(group, FAN_REPORT_TARGET_FID))))
1709-
goto path_put_and_out;
1710-
17111715
/* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */
17121716
if (mnt || !S_ISDIR(inode->i_mode)) {
17131717
mask &= ~FAN_EVENT_ON_CHILD;

include/linux/fanotify.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@
111111
FANOTIFY_PERM_EVENTS | \
112112
FAN_Q_OVERFLOW | FAN_ONDIR)
113113

114+
/* Events and flags relevant only for directories */
115+
#define FANOTIFY_DIRONLY_EVENT_BITS (FANOTIFY_DIRENT_EVENTS | \
116+
FAN_EVENT_ON_CHILD | FAN_ONDIR)
117+
114118
#define ALL_FANOTIFY_EVENT_BITS (FANOTIFY_OUTGOING_EVENTS | \
115119
FANOTIFY_EVENT_FLAGS)
116120

0 commit comments

Comments
 (0)