|
@@ -359,6 +359,11 @@ static int fanotify_release(struct inode *ignored, struct file *file)
|
|
|
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
|
|
|
struct fanotify_perm_event_info *event, *next;
|
|
|
|
|
|
+ /*
|
|
|
+ * There may be still new events arriving in the notification queue
|
|
|
+ * but since userspace cannot use fanotify fd anymore, no event can
|
|
|
+ * enter or leave access_list by now.
|
|
|
+ */
|
|
|
spin_lock(&group->fanotify_data.access_lock);
|
|
|
|
|
|
atomic_inc(&group->fanotify_data.bypass_perm);
|
|
@@ -373,6 +378,13 @@ static int fanotify_release(struct inode *ignored, struct file *file)
|
|
|
}
|
|
|
spin_unlock(&group->fanotify_data.access_lock);
|
|
|
|
|
|
+ /*
|
|
|
+ * Since bypass_perm is set, newly queued events will not wait for
|
|
|
+ * access response. Wake up the already sleeping ones now.
|
|
|
+ * synchronize_srcu() in fsnotify_destroy_group() will wait for all
|
|
|
+ * processes sleeping in fanotify_handle_event() waiting for access
|
|
|
+ * response and thus also for all permission events to be freed.
|
|
|
+ */
|
|
|
wake_up(&group->fanotify_data.access_waitq);
|
|
|
#endif
|
|
|
|