• Mike Kravetz's avatar
    hugetlb: fix null-ptr-deref in hugetlb_vma_lock_write · 187da0f8
    Mike Kravetz authored
    The routine __vma_private_lock tests for the existence of a reserve map
    associated with a private hugetlb mapping.  A pointer to the reserve map
    is in vma->vm_private_data.  __vma_private_lock was checking the pointer
    for NULL.  However, it is possible that the low bits of the pointer could
    be used as flags.  In such instances, vm_private_data is not NULL and not
    a valid pointer.  This results in the null-ptr-deref reported by syzbot:
    
    general protection fault, probably for non-canonical address 0xdffffc000000001d:
     0000 [#1] PREEMPT SMP KASAN
    KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
    CPU: 0 PID: 5048 Comm: syz-executor139 Not tainted 6.6.0-rc7-syzkaller-00142-g88
    8cf78c29e2 #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 1
    0/09/2023
    RIP: 0010:__lock_acquire+0x109/0x5de0 kernel/locking/lockdep.c:5004
    ...
    Call Trace:
     <TASK>
     lock_acquire kernel/locking/lockdep.c:5753 [inline]
     lock_acquire+0x1ae/0x510 kernel/locking/lockdep.c:5718
     down_write+0x93/0x200 kernel/locking/rwsem.c:1573
     hugetlb_vma_lock_write mm/hugetlb.c:300 [inline]
     hugetlb_vma_lock_write+0xae/0x100 mm/hugetlb.c:291
     __hugetlb_zap_begin+0x1e9/0x2b0 mm/hugetlb.c:5447
     hugetlb_zap_begin include/linux/hugetlb.h:258 [inline]
     unmap_vmas+0x2f4/0x470 mm/memory.c:1733
     exit_mmap+0x1ad/0xa60 mm/mmap.c:3230
     __mmput+0x12a/0x4d0 kernel/fork.c:1349
     mmput+0x62/0x70 kernel/fork.c:1371
     exit_mm kernel/exit.c:567 [inline]
     do_exit+0x9ad/0x2a20 kernel/exit.c:861
     __do_sys_exit kernel/exit.c:991 [inline]
     __se_sys_exit kernel/exit.c:989 [inline]
     __x64_sys_exit+0x42/0x50 kernel/exit.c:989
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    Mask off low bit flags before checking for NULL pointer.  In addition, the
    reserve map only 'belongs' to the OWNER (parent in parent/child
    relationships) so also check for the OWNER flag.
    
    Link: https://lkml.kernel.org/r/20231114012033.259600-1-mike.kravetz@oracle.com
    Reported-by: syzbot+6ada951e7c0f7bc8a71e@syzkaller.appspotmail.com
    Closes: https://lore.kernel.org/linux-mm/00000000000078d1e00608d7878b@google.com/
    Fixes: bf491692 ("hugetlbfs: extend hugetlb_vma_lock to private VMAs")
    Signed-off-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
    Reviewed-by: default avatarRik van Riel <riel@surriel.com>
    Cc: Edward Adam Davis <eadavis@qq.com>
    Cc: Muchun Song <muchun.song@linux.dev>
    Cc: Nathan Chancellor <nathan@kernel.org>
    Cc: Nick Desaulniers <ndesaulniers@google.com>
    Cc: Tom Rix <trix@redhat.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    187da0f8
hugetlb.c 215 KB