• Piotr Krysiuk's avatar
    bpf: Fix off-by-one for area size in creating mask to left · 10d2bb2e
    Piotr Krysiuk authored
    retrieve_ptr_limit() computes the ptr_limit for registers with stack and
    map_value type. ptr_limit is the size of the memory area that is still
    valid / in-bounds from the point of the current position and direction
    of the operation (add / sub). This size will later be used for masking
    the operation such that attempting out-of-bounds access in the speculative
    domain is redirected to remain within the bounds of the current map value.
    
    When masking to the right the size is correct, however, when masking to
    the left, the size is off-by-one which would lead to an incorrect mask
    and thus incorrect arithmetic operation in the non-speculative domain.
    Piotr found that if the resulting alu_limit value is zero, then the
    BPF_MOV32_IMM() from the fixup_bpf_calls() rewrite will end up loading
    0xffffffff into AX instead of sign-extending to the full 64 bit range,
    and as a result, this allows abuse for executing speculatively out-of-
    bounds loads against 4GB window of address space and thus extracting the
    contents of kernel memory via side-channel.
    
    Fixes: 979d63d5
    
     ("bpf: prevent out of bounds speculation on pointer arithmetic")
    Signed-off-by: default avatarPiotr Krysiuk <piotras@gmail.com>
    Co-developed-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    10d2bb2e
verifier.c 364 KB