@@ -424,11 +424,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
424
424
* events generated by the listener process itself, without disclosing
425
425
* the pids of other processes.
426
426
*/
427
- if (! capable ( CAP_SYS_ADMIN ) &&
427
+ if (FAN_GROUP_FLAG ( group , FANOTIFY_UNPRIV ) &&
428
428
task_tgid (current ) != event -> pid )
429
429
metadata .pid = 0 ;
430
430
431
- if (path && path -> mnt && path -> dentry ) {
431
+ /*
432
+ * For now, fid mode is required for an unprivileged listener and
433
+ * fid mode does not report fd in events. Keep this check anyway
434
+ * for safety in case fid mode requirement is relaxed in the future
435
+ * to allow unprivileged listener to get events with no fd and no fid.
436
+ */
437
+ if (!FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV ) &&
438
+ path && path -> mnt && path -> dentry ) {
432
439
fd = create_fd (group , path , & f );
433
440
if (fd < 0 )
434
441
return fd ;
@@ -1040,6 +1047,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1040
1047
int f_flags , fd ;
1041
1048
unsigned int fid_mode = flags & FANOTIFY_FID_BITS ;
1042
1049
unsigned int class = flags & FANOTIFY_CLASS_BITS ;
1050
+ unsigned int internal_flags = 0 ;
1043
1051
1044
1052
pr_debug ("%s: flags=%x event_f_flags=%x\n" ,
1045
1053
__func__ , flags , event_f_flags );
@@ -1053,6 +1061,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1053
1061
*/
1054
1062
if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) || !fid_mode )
1055
1063
return - EPERM ;
1064
+
1065
+ /*
1066
+ * Setting the internal flag FANOTIFY_UNPRIV on the group
1067
+ * prevents setting mount/filesystem marks on this group and
1068
+ * prevents reporting pid and open fd in events.
1069
+ */
1070
+ internal_flags |= FANOTIFY_UNPRIV ;
1056
1071
}
1057
1072
1058
1073
#ifdef CONFIG_AUDITSYSCALL
@@ -1105,7 +1120,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1105
1120
goto out_destroy_group ;
1106
1121
}
1107
1122
1108
- group -> fanotify_data .flags = flags ;
1123
+ group -> fanotify_data .flags = flags | internal_flags ;
1109
1124
group -> memcg = get_mem_cgroup_from_mm (current -> mm );
1110
1125
1111
1126
group -> fanotify_data .merge_hash = fanotify_alloc_merge_hash ();
@@ -1305,11 +1320,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1305
1320
group = f .file -> private_data ;
1306
1321
1307
1322
/*
1308
- * An unprivileged user is not allowed to watch a mount point nor
1309
- * a filesystem.
1323
+ * An unprivileged user is not allowed to setup mount nor filesystem
1324
+ * marks. This also includes setting up such marks by a group that
1325
+ * was initialized by an unprivileged user.
1310
1326
*/
1311
1327
ret = - EPERM ;
1312
- if (!capable (CAP_SYS_ADMIN ) &&
1328
+ if ((!capable (CAP_SYS_ADMIN ) ||
1329
+ FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV )) &&
1313
1330
mark_type != FAN_MARK_INODE )
1314
1331
goto fput_and_out ;
1315
1332
@@ -1460,6 +1477,7 @@ static int __init fanotify_user_setup(void)
1460
1477
max_marks = clamp (max_marks , FANOTIFY_OLD_DEFAULT_MAX_MARKS ,
1461
1478
FANOTIFY_DEFAULT_MAX_USER_MARKS );
1462
1479
1480
+ BUILD_BUG_ON (FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS );
1463
1481
BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_INIT_FLAGS ) != 10 );
1464
1482
BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_MARK_FLAGS ) != 9 );
1465
1483
0 commit comments