Skip to content

Commit c4ef28f

Browse files
committed
Merge tag 'fsnotify_for_v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fsnotify updates from Jan Kara: "A couple of small fsnotify fixes and cleanups" * tag 'fsnotify_for_v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fanotify: replace deprecated strcpy in fanotify_info_copy_{name,name2} fsnotify: inotify: pass mark connector to fsnotify_recalc_mask() fanotify: call fanotify_events_supported() before path_permission() and security_path_notify() fanotify: avoid/silence premature LSM capability checks inotify: fix watch count leak when fsnotify_add_inode_mark_locked() fails
2 parents 0480917 + 0fdbe84 commit c4ef28f

3 files changed

Lines changed: 28 additions & 30 deletions

File tree

fs/notify/fanotify/fanotify.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <linux/fsnotify_backend.h>
33
#include <linux/path.h>
44
#include <linux/slab.h>
5+
#include <linux/string.h>
56
#include <linux/exportfs.h>
67
#include <linux/hashtable.h>
78

@@ -218,7 +219,7 @@ static inline void fanotify_info_copy_name(struct fanotify_info *info,
218219
return;
219220

220221
info->name_len = name->len;
221-
strcpy(fanotify_info_name(info), name->name);
222+
strscpy(fanotify_info_name(info), name->name, name->len + 1);
222223
}
223224

224225
static inline void fanotify_info_copy_name2(struct fanotify_info *info,
@@ -228,7 +229,7 @@ static inline void fanotify_info_copy_name2(struct fanotify_info *info,
228229
return;
229230

230231
info->name2_len = name->len;
231-
strcpy(fanotify_info_name2(info), name->name);
232+
strscpy(fanotify_info_name2(info), name->name, name->len + 1);
232233
}
233234

234235
/*

fs/notify/fanotify/fanotify_user.c

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,7 @@ static int fanotify_find_path(int dfd, const char __user *filename,
12101210

12111211
*path = fd_file(f)->f_path;
12121212
path_get(path);
1213+
ret = 0;
12131214
} else {
12141215
unsigned int lookup_flags = 0;
12151216

@@ -1219,22 +1220,7 @@ static int fanotify_find_path(int dfd, const char __user *filename,
12191220
lookup_flags |= LOOKUP_DIRECTORY;
12201221

12211222
ret = user_path_at(dfd, filename, lookup_flags, path);
1222-
if (ret)
1223-
goto out;
1224-
}
1225-
1226-
/* you can only watch an inode if you have read permissions on it */
1227-
ret = path_permission(path, MAY_READ);
1228-
if (ret) {
1229-
path_put(path);
1230-
goto out;
12311223
}
1232-
1233-
ret = security_path_notify(path, mask, obj_type);
1234-
if (ret)
1235-
path_put(path);
1236-
1237-
out:
12381224
return ret;
12391225
}
12401226

@@ -1615,17 +1601,18 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
16151601
pr_debug("%s: flags=%x event_f_flags=%x\n",
16161602
__func__, flags, event_f_flags);
16171603

1618-
if (!capable(CAP_SYS_ADMIN)) {
1619-
/*
1620-
* An unprivileged user can setup an fanotify group with
1621-
* limited functionality - an unprivileged group is limited to
1622-
* notification events with file handles or mount ids and it
1623-
* cannot use unlimited queue/marks.
1624-
*/
1625-
if ((flags & FANOTIFY_ADMIN_INIT_FLAGS) ||
1626-
!(flags & (FANOTIFY_FID_BITS | FAN_REPORT_MNT)))
1627-
return -EPERM;
1604+
/*
1605+
* An unprivileged user can setup an fanotify group with limited
1606+
* functionality - an unprivileged group is limited to notification
1607+
* events with file handles or mount ids and it cannot use unlimited
1608+
* queue/marks.
1609+
*/
1610+
if (((flags & FANOTIFY_ADMIN_INIT_FLAGS) ||
1611+
!(flags & (FANOTIFY_FID_BITS | FAN_REPORT_MNT))) &&
1612+
!capable(CAP_SYS_ADMIN))
1613+
return -EPERM;
16281614

1615+
if (!ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) {
16291616
/*
16301617
* Setting the internal flag FANOTIFY_UNPRIV on the group
16311618
* prevents setting mount/filesystem marks on this group and
@@ -1990,8 +1977,8 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19901977
* A user is allowed to setup sb/mount/mntns marks only if it is
19911978
* capable in the user ns where the group was created.
19921979
*/
1993-
if (!ns_capable(group->user_ns, CAP_SYS_ADMIN) &&
1994-
mark_type != FAN_MARK_INODE)
1980+
if (mark_type != FAN_MARK_INODE &&
1981+
!ns_capable(group->user_ns, CAP_SYS_ADMIN))
19951982
return -EPERM;
19961983

19971984
/*
@@ -2057,6 +2044,15 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
20572044
goto path_put_and_out;
20582045
}
20592046

2047+
/* you can only watch an inode if you have read permissions on it */
2048+
ret = path_permission(&path, MAY_READ);
2049+
if (ret)
2050+
goto path_put_and_out;
2051+
2052+
ret = security_path_notify(&path, mask, obj_type);
2053+
if (ret)
2054+
goto path_put_and_out;
2055+
20602056
if (fid_mode) {
20612057
ret = fanotify_test_fsid(path.dentry, flags, &__fsid);
20622058
if (ret)

fs/notify/inotify/inotify_user.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
573573

574574
/* update the inode with this new fsn_mark */
575575
if (dropped || do_inode)
576-
fsnotify_recalc_mask(inode->i_fsnotify_marks);
576+
fsnotify_recalc_mask(fsn_mark->connector);
577577

578578
}
579579

@@ -621,6 +621,7 @@ static int inotify_new_watch(struct fsnotify_group *group,
621621
if (ret) {
622622
/* we failed to get on the inode, get off the idr */
623623
inotify_remove_from_idr(group, tmp_i_mark);
624+
dec_inotify_watches(group->inotify_data.ucounts);
624625
goto out_err;
625626
}
626627

0 commit comments

Comments
 (0)