Skip to content
  • Greg Thelen's avatar
    tmpfs: fix use-after-free of mempolicy object · 06c7976c
    Greg Thelen authored
    
    
    commit 5f00110f7273f9ff04ac69a5f85bb535a4fd0987 upstream.
    
    The tmpfs remount logic preserves filesystem mempolicy if the mpol=M
    option is not specified in the remount request.  A new policy can be
    specified if mpol=M is given.
    
    Before this patch remounting an mpol bound tmpfs without specifying
    mpol= mount option in the remount request would set the filesystem's
    mempolicy object to a freed mempolicy object.
    
    To reproduce the problem boot a DEBUG_PAGEALLOC kernel and run:
        # mkdir /tmp/x
    
        # mount -t tmpfs -o size=100M,mpol=interleave nodev /tmp/x
    
        # grep /tmp/x /proc/mounts
        nodev /tmp/x tmpfs rw,relatime,size=102400k,mpol=interleave:0-3 0 0
    
        # mount -o remount,size=200M nodev /tmp/x
    
        # grep /tmp/x /proc/mounts
        nodev /tmp/x tmpfs rw,relatime,size=204800k,mpol=??? 0 0
            # note ? garbage in mpol=... output above
    
        # dd if=/dev/zero of=/tmp/x/f count=1
            # panic here
    
    Panic:
        BUG: unable to handle kernel NULL pointer dereference at           (null)
        IP: [<          (null)>]           (null)
        [...]
        Oops: 0010 [#1] SMP DEBUG_PAGEALLOC
        Call Trace:
          mpol_shared_policy_init+0xa5/0x160
          shmem_get_inode+0x209/0x270
          shmem_mknod+0x3e/0xf0
          shmem_create+0x18/0x20
          vfs_create+0xb5/0x130
          do_last+0x9a1/0xea0
          path_openat+0xb3/0x4d0
          do_filp_open+0x42/0xa0
          do_sys_open+0xfe/0x1e0
          compat_sys_open+0x1b/0x20
          cstar_dispatch+0x7/0x1f
    
    Non-debug kernels will not crash immediately because referencing the
    dangling mpol will not cause a fault.  Instead the filesystem will
    reference a freed mempolicy object, which will cause unpredictable
    behavior.
    
    The problem boils down to a dropped mpol reference below if
    shmem_parse_options() does not allocate a new mpol:
    
        config = *sbinfo
        shmem_parse_options(data, &config, true)
        mpol_put(sbinfo->mpol)
        sbinfo->mpol = config.mpol  /* BUG: saves unreferenced mpol */
    
    This patch avoids the crash by not releasing the mempolicy if
    shmem_parse_options() doesn't create a new mpol.
    
    How far back does this issue go? I see it in both 2.6.36 and 3.3.  I did
    not look back further.
    
    Signed-off-by: default avatarGreg Thelen <gthelen@google.com>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    06c7976c