5050
5151/* configurable via /proc/sys/fs/fanotify/ */
5252static int fanotify_max_queued_events __read_mostly ;
53+ static int perm_group_timeout __read_mostly ;
5354
5455#ifdef CONFIG_SYSCTL
5556
@@ -85,6 +86,14 @@ static const struct ctl_table fanotify_table[] = {
8586 .proc_handler = proc_dointvec_minmax ,
8687 .extra1 = SYSCTL_ZERO
8788 },
89+ {
90+ .procname = "watchdog_timeout" ,
91+ .data = & perm_group_timeout ,
92+ .maxlen = sizeof (int ),
93+ .mode = 0644 ,
94+ .proc_handler = proc_dointvec_minmax ,
95+ .extra1 = SYSCTL_ZERO ,
96+ },
8897};
8998
9099static void __init fanotify_sysctls_init (void )
@@ -95,6 +104,91 @@ static void __init fanotify_sysctls_init(void)
95104#define fanotify_sysctls_init () do { } while (0)
96105#endif /* CONFIG_SYSCTL */
97106
107+ static LIST_HEAD (perm_group_list );
108+ static DEFINE_SPINLOCK (perm_group_lock );
109+ static void perm_group_watchdog (struct work_struct * work );
110+ static DECLARE_DELAYED_WORK (perm_group_work , perm_group_watchdog ) ;
111+
112+ static void perm_group_watchdog_schedule (void )
113+ {
114+ schedule_delayed_work (& perm_group_work , secs_to_jiffies (perm_group_timeout ));
115+ }
116+
117+ static void perm_group_watchdog (struct work_struct * work )
118+ {
119+ struct fsnotify_group * group ;
120+ struct fanotify_perm_event * event ;
121+ struct task_struct * task ;
122+ pid_t failed_pid = 0 ;
123+
124+ guard (spinlock )(& perm_group_lock );
125+ if (list_empty (& perm_group_list ))
126+ return ;
127+
128+ list_for_each_entry (group , & perm_group_list ,
129+ fanotify_data .perm_grp_list ) {
130+ /*
131+ * Ok to test without lock, racing with an addition is
132+ * fine, will deal with it next round
133+ */
134+ if (list_empty (& group -> fanotify_data .access_list ))
135+ continue ;
136+
137+ spin_lock (& group -> notification_lock );
138+ list_for_each_entry (event , & group -> fanotify_data .access_list ,
139+ fae .fse .list ) {
140+ if (likely (event -> watchdog_cnt == 0 )) {
141+ event -> watchdog_cnt = 1 ;
142+ } else if (event -> watchdog_cnt == 1 ) {
143+ /* Report on event only once */
144+ event -> watchdog_cnt = 2 ;
145+
146+ /* Do not report same pid repeatedly */
147+ if (event -> recv_pid == failed_pid )
148+ continue ;
149+
150+ failed_pid = event -> recv_pid ;
151+ rcu_read_lock ();
152+ task = find_task_by_pid_ns (event -> recv_pid ,
153+ & init_pid_ns );
154+ pr_warn_ratelimited (
155+ "PID %u (%s) failed to respond to fanotify queue for more than %d seconds\n" ,
156+ event -> recv_pid ,
157+ task ? task -> comm : NULL ,
158+ perm_group_timeout );
159+ rcu_read_unlock ();
160+ }
161+ }
162+ spin_unlock (& group -> notification_lock );
163+ }
164+ perm_group_watchdog_schedule ();
165+ }
166+
167+ static void fanotify_perm_watchdog_group_remove (struct fsnotify_group * group )
168+ {
169+ if (!list_empty (& group -> fanotify_data .perm_grp_list )) {
170+ /* Perm event watchdog can no longer scan this group. */
171+ spin_lock (& perm_group_lock );
172+ list_del_init (& group -> fanotify_data .perm_grp_list );
173+ spin_unlock (& perm_group_lock );
174+ }
175+ }
176+
177+ static void fanotify_perm_watchdog_group_add (struct fsnotify_group * group )
178+ {
179+ if (!perm_group_timeout )
180+ return ;
181+
182+ spin_lock (& perm_group_lock );
183+ if (list_empty (& group -> fanotify_data .perm_grp_list )) {
184+ /* Add to perm_group_list for monitoring by watchdog. */
185+ if (list_empty (& perm_group_list ))
186+ perm_group_watchdog_schedule ();
187+ list_add_tail (& group -> fanotify_data .perm_grp_list , & perm_group_list );
188+ }
189+ spin_unlock (& perm_group_lock );
190+ }
191+
98192/*
99193 * All flags that may be specified in parameter event_f_flags of fanotify_init.
100194 *
@@ -953,6 +1047,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
9531047 spin_lock (& group -> notification_lock );
9541048 list_add_tail (& event -> fse .list ,
9551049 & group -> fanotify_data .access_list );
1050+ FANOTIFY_PERM (event )-> recv_pid = current -> pid ;
9561051 spin_unlock (& group -> notification_lock );
9571052 }
9581053 }
@@ -1012,6 +1107,8 @@ static int fanotify_release(struct inode *ignored, struct file *file)
10121107 */
10131108 fsnotify_group_stop_queueing (group );
10141109
1110+ fanotify_perm_watchdog_group_remove (group );
1111+
10151112 /*
10161113 * Process all permission events on access_list and notification queue
10171114 * and simulate reply from userspace.
@@ -1465,6 +1562,10 @@ static int fanotify_add_mark(struct fsnotify_group *group,
14651562 fsnotify_group_unlock (group );
14661563
14671564 fsnotify_put_mark (fsn_mark );
1565+
1566+ if (!ret && (mask & FANOTIFY_PERM_EVENTS ))
1567+ fanotify_perm_watchdog_group_add (group );
1568+
14681569 return ret ;
14691570}
14701571
@@ -1625,6 +1726,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
16251726 group -> fanotify_data .f_flags = event_f_flags ;
16261727 init_waitqueue_head (& group -> fanotify_data .access_waitq );
16271728 INIT_LIST_HEAD (& group -> fanotify_data .access_list );
1729+ INIT_LIST_HEAD (& group -> fanotify_data .perm_grp_list );
16281730 switch (class ) {
16291731 case FAN_CLASS_NOTIF :
16301732 group -> priority = FSNOTIFY_PRIO_NORMAL ;
@@ -1999,7 +2101,10 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19992101 user_ns = path .mnt -> mnt_sb -> s_user_ns ;
20002102 obj = path .mnt -> mnt_sb ;
20012103 } else if (obj_type == FSNOTIFY_OBJ_TYPE_MNTNS ) {
2104+ ret = - EINVAL ;
20022105 mntns = mnt_ns_from_dentry (path .dentry );
2106+ if (!mntns )
2107+ goto path_put_and_out ;
20032108 user_ns = mntns -> user_ns ;
20042109 obj = mntns ;
20052110 }
0 commit comments