• Eryu Guan's avatar
    fs/binfmt_misc.c: node could be NULL when evicting inode · 7e866006
    Eryu Guan authored
    inode->i_private is assigned by a Node pointer only after registering a
    new binary format, so it could be NULL if inode was created by
    bm_fill_super() (or iput() was called by the error path in
    bm_register_write()), and this could result in NULL pointer dereference
    when evicting such an inode.  e.g.  mount binfmt_misc filesystem then
    umount it immediately:
    
      mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
      umount /proc/sys/fs/binfmt_misc
    
    will result in
    
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000013
      IP: bm_evict_inode+0x16/0x40 [binfmt_misc]
      ...
      Call Trace:
       evict+0xd3/0x1a0
       iput+0x17d/0x1d0
       dentry_unlink_inode+0xb9/0xf0
       __dentry_kill+0xc7/0x170
       shrink_dentry_list+0x122/0x280
       shrink_dcache_parent+0x39/0x90
       do_one_tree+0x12/0x40
       shrink_dcache_for_umount+0x2d/0x90
       generic_shutdown_super+0x1f/0x120
       kill_litter_super+0x29/0x40
       deactivate_locked_super+0x43/0x70
       deactivate_super+0x45/0x60
       cleanup_mnt+0x3f/0x70
       __cleanup_mnt+0x12/0x20
       task_work_run+0x86/0xa0
       exit_to_usermode_loop+0x6d/0x99
       syscall_return_slowpath+0xba/0xf0
       entry_SYSCALL_64_fastpath+0xa3/0xa
    
    Fix it by making sure Node (e) is not NULL.
    
    Link: http://lkml.kernel.org/r/20171010100642.31786-1-eguan@redhat.com
    Fixes: 83f91827 ("exec: binfmt_misc: shift filp_close(interp_file) from kill_node() to bm_evict_inode()")
    Signed-off-by: default avatarEryu Guan <eguan@redhat.com>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    7e866006
binfmt_misc.c 18.2 KB