• Daniel Borkmann's avatar
    bpf: Fix out of bounds access for ringbuf helpers · 64620e0a
    Daniel Borkmann authored
    Both bpf_ringbuf_submit() and bpf_ringbuf_discard() have ARG_PTR_TO_ALLOC_MEM
    in their bpf_func_proto definition as their first argument. They both expect
    the result from a prior bpf_ringbuf_reserve() call which has a return type of
    RET_PTR_TO_ALLOC_MEM_OR_NULL.
    
    Meaning, after a NULL check in the code, the verifier will promote the register
    type in the non-NULL branch to a PTR_TO_MEM and in the NULL branch to a known
    zero scalar. Generally, pointer arithmetic on PTR_TO_MEM is allowed, so the
    latter could have an offset.
    
    The ARG_PTR_TO_ALLOC_MEM expects a PTR_TO_MEM register type. However, the non-
    zero result from bpf_ringbuf_reserve() must be fed into either bpf_ringbuf_submit()
    or bpf_ringbuf_discard() but with the original offset given it will then read
    out the struct bpf_ringbuf_hdr mapping.
    
    The verifier missed to enforce a zero offset, so that out of bounds access
    can be triggered which could be used to escalate privileges if unprivileged
    BPF was enabled (disabled by default in kernel).
    
    Fixes: 457f4436 ("bpf: Implement BPF ring buffer and verifier support for it")
    Reported-by: <tr3e.wang@gmail.com> (SecCoder Security Lab)
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    64620e0a
verifier.c 410 KB