• Paolo Bonzini's avatar
    KVM: MMU: Fix ubsan warnings · 0a47cd85
    Paolo Bonzini authored
    kvm_mmu_pages_init is doing some really yucky stuff.  It is setting
    up a sentinel for mmu_page_clear_parents; however, because of a) the
    way levels are numbered starting from 1 and b) the way mmu_page_path
    sizes its arrays with PT64_ROOT_LEVEL-1 elements, the access can be
    out of bounds.  This is harmless because the code overwrites up to the
    first two elements of parents->idx and these are initialized, and
    because the sentinel is not needed in this case---mmu_page_clear_parents
    exits anyway when it gets to the end of the array.  However ubsan
    complains, and everyone else should too.
    
    This fix does three things.  First it makes the mmu_page_path arrays
    PT64_ROOT_LEVEL elements in size, so that we can write to them without
    checking the level in advance.  Second it disintegrates kvm_mmu_pages_init
    between mmu_unsync_walk (to reset the struct kvm_mmu_pages) and
    for_each_sp (to place the NULL sentinel at the end of the current path).
    This is okay because the mmu_page_path is only used in
    mmu_pages_clear_parents; mmu_pages_clear_parents itself is called within
    a for_each_sp iterator, and hence always after a call to mmu_pages_next.
    Third it changes mmu_pages_clear_parents to just use the sentinel to
    stop iteration, without checking the bounds on level.
    Reported-by: default avatarSasha Levin <sasha.levin@oracle.com>
    Reported-by: default avatarMike Krinkin <krinkin.m.u@gmail.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    0a47cd85
mmu.c 126 KB