@@ -1334,6 +1334,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
1334
1334
* A group with FAN_UNLIMITED_MARKS does not contribute to mark count
1335
1335
* in the limited groups account.
1336
1336
*/
1337
+ BUILD_BUG_ON (!(FANOTIFY_ADMIN_INIT_FLAGS & FAN_UNLIMITED_MARKS ));
1337
1338
if (!FAN_GROUP_FLAG (group , FAN_UNLIMITED_MARKS ) &&
1338
1339
!inc_ucount (ucounts -> ns , ucounts -> uid , UCOUNT_FANOTIFY_MARKS ))
1339
1340
return ERR_PTR (- ENOSPC );
@@ -1498,6 +1499,7 @@ static struct hlist_head *fanotify_alloc_merge_hash(void)
1498
1499
/* fanotify syscalls */
1499
1500
SYSCALL_DEFINE2 (fanotify_init , unsigned int , flags , unsigned int , event_f_flags )
1500
1501
{
1502
+ struct user_namespace * user_ns = current_user_ns ();
1501
1503
struct fsnotify_group * group ;
1502
1504
int f_flags , fd ;
1503
1505
unsigned int fid_mode = flags & FANOTIFY_FID_BITS ;
@@ -1512,10 +1514,11 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1512
1514
/*
1513
1515
* An unprivileged user can setup an fanotify group with
1514
1516
* 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.
1517
1519
*/
1518
- if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) || !fid_mode )
1520
+ if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) ||
1521
+ !(flags & (FANOTIFY_FID_BITS | FAN_REPORT_MNT )))
1519
1522
return - EPERM ;
1520
1523
1521
1524
/*
@@ -1594,8 +1597,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1594
1597
}
1595
1598
1596
1599
/* 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 (),
1599
1601
UCOUNT_FANOTIFY_GROUPS );
1600
1602
if (!group -> fanotify_data .ucounts ) {
1601
1603
fd = - EMFILE ;
@@ -1604,6 +1606,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1604
1606
1605
1607
group -> fanotify_data .flags = flags | internal_flags ;
1606
1608
group -> memcg = get_mem_cgroup_from_mm (current -> mm );
1609
+ group -> user_ns = get_user_ns (user_ns );
1607
1610
1608
1611
group -> fanotify_data .merge_hash = fanotify_alloc_merge_hash ();
1609
1612
if (!group -> fanotify_data .merge_hash ) {
@@ -1637,21 +1640,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1637
1640
goto out_destroy_group ;
1638
1641
}
1639
1642
1643
+ BUILD_BUG_ON (!(FANOTIFY_ADMIN_INIT_FLAGS & FAN_UNLIMITED_QUEUE ));
1640
1644
if (flags & FAN_UNLIMITED_QUEUE ) {
1641
- fd = - EPERM ;
1642
- if (!capable (CAP_SYS_ADMIN ))
1643
- goto out_destroy_group ;
1644
1645
group -> max_events = UINT_MAX ;
1645
1646
} else {
1646
1647
group -> max_events = fanotify_max_queued_events ;
1647
1648
}
1648
1649
1649
- if (flags & FAN_UNLIMITED_MARKS ) {
1650
- fd = - EPERM ;
1651
- if (!capable (CAP_SYS_ADMIN ))
1652
- goto out_destroy_group ;
1653
- }
1654
-
1655
1650
if (flags & FAN_ENABLE_AUDIT ) {
1656
1651
fd = - EPERM ;
1657
1652
if (!capable (CAP_AUDIT_WRITE ))
@@ -1811,6 +1806,8 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1811
1806
struct fsnotify_group * group ;
1812
1807
struct path path ;
1813
1808
struct fan_fsid __fsid , * fsid = NULL ;
1809
+ struct user_namespace * user_ns = NULL ;
1810
+ struct mnt_namespace * mntns ;
1814
1811
u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS ;
1815
1812
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS ;
1816
1813
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,
1904
1901
}
1905
1902
1906
1903
/*
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.
1910
1906
*/
1911
- if ((!capable (CAP_SYS_ADMIN ) ||
1912
- FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV )) &&
1907
+ if (!ns_capable (group -> user_ns , CAP_SYS_ADMIN ) &&
1913
1908
mark_type != FAN_MARK_INODE )
1914
1909
return - EPERM ;
1915
1910
@@ -1988,18 +1983,31 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1988
1983
fsid = & __fsid ;
1989
1984
}
1990
1985
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
+ */
1992
1992
if (obj_type == FSNOTIFY_OBJ_TYPE_INODE ) {
1993
1993
inode = path .dentry -> d_inode ;
1994
1994
obj = inode ;
1995
1995
} else if (obj_type == FSNOTIFY_OBJ_TYPE_VFSMOUNT ) {
1996
+ user_ns = path .mnt -> mnt_sb -> s_user_ns ;
1996
1997
obj = path .mnt ;
1997
1998
} else if (obj_type == FSNOTIFY_OBJ_TYPE_SB ) {
1999
+ user_ns = path .mnt -> mnt_sb -> s_user_ns ;
1998
2000
obj = path .mnt -> mnt_sb ;
1999
2001
} 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 ;
2001
2005
}
2002
2006
2007
+ ret = - EPERM ;
2008
+ if (user_ns && !ns_capable (user_ns , CAP_SYS_ADMIN ))
2009
+ goto path_put_and_out ;
2010
+
2003
2011
ret = - EINVAL ;
2004
2012
if (!obj )
2005
2013
goto path_put_and_out ;
0 commit comments