@@ -424,11 +424,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
424424 * events generated by the listener process itself, without disclosing
425425 * the pids of other processes.
426426 */
427- if (! capable ( CAP_SYS_ADMIN ) &&
427+ if (FAN_GROUP_FLAG ( group , FANOTIFY_UNPRIV ) &&
428428 task_tgid (current ) != event -> pid )
429429 metadata .pid = 0 ;
430430
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 ) {
432439 fd = create_fd (group , path , & f );
433440 if (fd < 0 )
434441 return fd ;
@@ -1040,6 +1047,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
10401047 int f_flags , fd ;
10411048 unsigned int fid_mode = flags & FANOTIFY_FID_BITS ;
10421049 unsigned int class = flags & FANOTIFY_CLASS_BITS ;
1050+ unsigned int internal_flags = 0 ;
10431051
10441052 pr_debug ("%s: flags=%x event_f_flags=%x\n" ,
10451053 __func__ , flags , event_f_flags );
@@ -1053,6 +1061,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
10531061 */
10541062 if ((flags & FANOTIFY_ADMIN_INIT_FLAGS ) || !fid_mode )
10551063 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 ;
10561071 }
10571072
10581073#ifdef CONFIG_AUDITSYSCALL
@@ -1105,7 +1120,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
11051120 goto out_destroy_group ;
11061121 }
11071122
1108- group -> fanotify_data .flags = flags ;
1123+ group -> fanotify_data .flags = flags | internal_flags ;
11091124 group -> memcg = get_mem_cgroup_from_mm (current -> mm );
11101125
11111126 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,
13051320 group = f .file -> private_data ;
13061321
13071322 /*
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.
13101326 */
13111327 ret = - EPERM ;
1312- if (!capable (CAP_SYS_ADMIN ) &&
1328+ if ((!capable (CAP_SYS_ADMIN ) ||
1329+ FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV )) &&
13131330 mark_type != FAN_MARK_INODE )
13141331 goto fput_and_out ;
13151332
@@ -1460,6 +1477,7 @@ static int __init fanotify_user_setup(void)
14601477 max_marks = clamp (max_marks , FANOTIFY_OLD_DEFAULT_MAX_MARKS ,
14611478 FANOTIFY_DEFAULT_MAX_USER_MARKS );
14621479
1480+ BUILD_BUG_ON (FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS );
14631481 BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_INIT_FLAGS ) != 10 );
14641482 BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_MARK_FLAGS ) != 9 );
14651483
0 commit comments