fanotify: fix double free of pending permission events
[cascardo/linux.git] / fs / notify / fanotify / fanotify_user.c
index 3fdc8a3..b13992a 100644 (file)
@@ -66,7 +66,7 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
 
        /* held the notification_mutex the whole time, so this is the
         * same event we peeked above */
-       return fsnotify_remove_notify_event(group);
+       return fsnotify_remove_first_event(group);
 }
 
 static int create_fd(struct fsnotify_group *group,
@@ -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