fsnotify: don't put user context if it was never assigned
authorSasha Levin <sasha.levin@oracle.com>
Thu, 9 Oct 2014 22:24:37 +0000 (15:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Oct 2014 02:25:45 +0000 (22:25 -0400)
On some failure paths we may attempt to free user context even if it
wasn't assigned yet.  This will cause a NULL ptr deref and a kernel BUG.

The path I was looking at is in inotify_new_group():

        oevent = kmalloc(sizeof(struct inotify_event_info), GFP_KERNEL);
        if (unlikely(!oevent)) {
                fsnotify_destroy_group(group);
                return ERR_PTR(-ENOMEM);
        }

fsnotify_destroy_group() would get called here, but
group->inotify_data.user is only getting assigned later:

group->inotify_data.user = get_current_user();

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: John McCutchan <john@johnmccutchan.com>
Cc: Robert Love <rlove@rlove.org>
Cc: Eric Paris <eparis@parisplace.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/notify/inotify/inotify_fsnotify.c

index 0f88bc0..7d888d7 100644 (file)
@@ -165,8 +165,10 @@ static void inotify_free_group_priv(struct fsnotify_group *group)
        /* ideally the idr is empty and we won't hit the BUG in the callback */
        idr_for_each(&group->inotify_data.idr, idr_callback, group);
        idr_destroy(&group->inotify_data.idr);
-       atomic_dec(&group->inotify_data.user->inotify_devs);
-       free_uid(group->inotify_data.user);
+       if (group->inotify_data.user) {
+               atomic_dec(&group->inotify_data.user->inotify_devs);
+               free_uid(group->inotify_data.user);
+       }
 }
 
 static void inotify_free_event(struct fsnotify_event *fsn_event)