@@ -1334,6 +1334,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
13341334 * A group with FAN_UNLIMITED_MARKS does not contribute to mark count
13351335 * in the limited groups account.
13361336 */
1337+ BUILD_BUG_ON (!(FANOTIFY_ADMIN_INIT_FLAGS & FAN_UNLIMITED_MARKS ));
13371338 if (!FAN_GROUP_FLAG (group , FAN_UNLIMITED_MARKS ) &&
13381339 !inc_ucount (ucounts -> ns , ucounts -> uid , UCOUNT_FANOTIFY_MARKS ))
13391340 return ERR_PTR (- ENOSPC );
@@ -1498,6 +1499,7 @@ static struct hlist_head *fanotify_alloc_merge_hash(void)
14981499/* fanotify syscalls */
14991500SYSCALL_DEFINE2 (fanotify_init , unsigned int , flags , unsigned int , event_f_flags )
15001501{
1502+ struct user_namespace * user_ns = current_user_ns ();
15011503 struct fsnotify_group * group ;
15021504 int f_flags , fd ;
15031505 unsigned int fid_mode = flags & FANOTIFY_FID_BITS ;
@@ -1512,10 +1514,11 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
15121514 /*
15131515 * An unprivileged user can setup an fanotify group with
15141516 * limited functionality - an unprivileged group is limited to
1515- * notification events with file handles and it cannot use
1516- * unlimited queue/marks.
1517+ * notification events with file handles or mount ids and it
1518+ * cannot use unlimited queue/marks.
15171519 */
1518- if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) || !fid_mode )
1520+ if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) ||
1521+ !(flags & (FANOTIFY_FID_BITS | FAN_REPORT_MNT )))
15191522 return - EPERM ;
15201523
15211524 /*
@@ -1594,8 +1597,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
15941597 }
15951598
15961599 /* Enforce groups limits per user in all containing user ns */
1597- group -> fanotify_data .ucounts = inc_ucount (current_user_ns (),
1598- current_euid (),
1600+ group -> fanotify_data .ucounts = inc_ucount (user_ns , current_euid (),
15991601 UCOUNT_FANOTIFY_GROUPS );
16001602 if (!group -> fanotify_data .ucounts ) {
16011603 fd = - EMFILE ;
@@ -1604,6 +1606,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
16041606
16051607 group -> fanotify_data .flags = flags | internal_flags ;
16061608 group -> memcg = get_mem_cgroup_from_mm (current -> mm );
1609+ group -> user_ns = get_user_ns (user_ns );
16071610
16081611 group -> fanotify_data .merge_hash = fanotify_alloc_merge_hash ();
16091612 if (!group -> fanotify_data .merge_hash ) {
@@ -1637,21 +1640,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
16371640 goto out_destroy_group ;
16381641 }
16391642
1643+ BUILD_BUG_ON (!(FANOTIFY_ADMIN_INIT_FLAGS & FAN_UNLIMITED_QUEUE ));
16401644 if (flags & FAN_UNLIMITED_QUEUE ) {
1641- fd = - EPERM ;
1642- if (!capable (CAP_SYS_ADMIN ))
1643- goto out_destroy_group ;
16441645 group -> max_events = UINT_MAX ;
16451646 } else {
16461647 group -> max_events = fanotify_max_queued_events ;
16471648 }
16481649
1649- if (flags & FAN_UNLIMITED_MARKS ) {
1650- fd = - EPERM ;
1651- if (!capable (CAP_SYS_ADMIN ))
1652- goto out_destroy_group ;
1653- }
1654-
16551650 if (flags & FAN_ENABLE_AUDIT ) {
16561651 fd = - EPERM ;
16571652 if (!capable (CAP_AUDIT_WRITE ))
@@ -1811,6 +1806,8 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
18111806 struct fsnotify_group * group ;
18121807 struct path path ;
18131808 struct fan_fsid __fsid , * fsid = NULL ;
1809+ struct user_namespace * user_ns = NULL ;
1810+ struct mnt_namespace * mntns ;
18141811 u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS ;
18151812 unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS ;
18161813 unsigned int mark_cmd = flags & FANOTIFY_MARK_CMD_BITS ;
@@ -1904,12 +1901,10 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19041901 }
19051902
19061903 /*
1907- * An unprivileged user is not allowed to setup mount nor filesystem
1908- * marks. This also includes setting up such marks by a group that
1909- * was initialized by an unprivileged user.
1904+ * A user is allowed to setup sb/mount/mntns marks only if it is
1905+ * capable in the user ns where the group was created.
19101906 */
1911- if ((!capable (CAP_SYS_ADMIN ) ||
1912- FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV )) &&
1907+ if (!ns_capable (group -> user_ns , CAP_SYS_ADMIN ) &&
19131908 mark_type != FAN_MARK_INODE )
19141909 return - EPERM ;
19151910
@@ -1988,18 +1983,31 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19881983 fsid = & __fsid ;
19891984 }
19901985
1991- /* inode held in place by reference to path; group by fget on fd */
1986+ /*
1987+ * In addition to being capable in the user ns where group was created,
1988+ * the user also needs to be capable in the user ns associated with
1989+ * the filesystem or in the user ns associated with the mntns
1990+ * (when marking mntns).
1991+ */
19921992 if (obj_type == FSNOTIFY_OBJ_TYPE_INODE ) {
19931993 inode = path .dentry -> d_inode ;
19941994 obj = inode ;
19951995 } else if (obj_type == FSNOTIFY_OBJ_TYPE_VFSMOUNT ) {
1996+ user_ns = path .mnt -> mnt_sb -> s_user_ns ;
19961997 obj = path .mnt ;
19971998 } else if (obj_type == FSNOTIFY_OBJ_TYPE_SB ) {
1999+ user_ns = path .mnt -> mnt_sb -> s_user_ns ;
19982000 obj = path .mnt -> mnt_sb ;
19992001 } else if (obj_type == FSNOTIFY_OBJ_TYPE_MNTNS ) {
2000- obj = mnt_ns_from_dentry (path .dentry );
2002+ mntns = mnt_ns_from_dentry (path .dentry );
2003+ user_ns = mntns -> user_ns ;
2004+ obj = mntns ;
20012005 }
20022006
2007+ ret = - EPERM ;
2008+ if (user_ns && !ns_capable (user_ns , CAP_SYS_ADMIN ))
2009+ goto path_put_and_out ;
2010+
20032011 ret = - EINVAL ;
20042012 if (!obj )
20052013 goto path_put_and_out ;
0 commit comments