• Sean Christopherson's avatar
    hugetlbfs: fix off-by-one error in hugetlb_vmdelete_list() · d6aba4c8
    Sean Christopherson authored
    Pass "end - 1" instead of "end" when walking the interval tree in
    hugetlb_vmdelete_list() to fix an inclusive vs.  exclusive bug.  The two
    callers that pass a non-zero "end" treat it as exclusive, whereas the
    interval tree iterator expects an inclusive "last".  E.g.  punching a
    hole in a file that precisely matches the size of a single hugepage,
    with a vma starting right on the boundary, will result in
    unmap_hugepage_range() being called twice, with the second call having
    start==end.
    
    The off-by-one error doesn't cause functional problems as
    __unmap_hugepage_range() turns into a massive nop due to
    short-circuiting its for-loop on "address < end".  But, the mmu_notifier
    invocations to invalid_range_{start,end}() are passed a bogus zero-sized
    range, which may be unexpected behavior for secondary MMUs.
    
    The bug was exposed by commit ed922739 ("KVM: Use interval tree to
    do fast hva lookup in memslots"), currently queued in the KVM tree for
    5.17, which added a WARN to detect ranges with start==end.
    
    Link: https://lkml.kernel.org/r/20211228234257.1926057-1-seanjc@google.com
    Fixes: 1bfad99a ("hugetlbfs: hugetlb_vmtruncate_list() needs to take a range to delete")
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Reported-by: syzbot+4e697fe80a31aa7efe21@syzkaller.appspotmail.com
    Reviewed-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d6aba4c8
inode.c 41 KB