• Kumar Kartikeya Dwivedi's avatar
    bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR · 79168a66
    Kumar Kartikeya Dwivedi authored
    Currently, the dynptr function is not checking the variable offset part
    of PTR_TO_STACK that it needs to check. The fixed offset is considered
    when computing the stack pointer index, but if the variable offset was
    not a constant (such that it could not be accumulated in reg->off), we
    will end up a discrepency where runtime pointer does not point to the
    actual stack slot we mark as STACK_DYNPTR.
    
    It is impossible to precisely track dynptr state when variable offset is
    not constant, hence, just like bpf_timer, kptr, bpf_spin_lock, etc.
    simply reject the case where reg->var_off is not constant. Then,
    consider both reg->off and reg->var_off.value when computing the stack
    pointer index.
    
    A new helper dynptr_get_spi is introduced to hide over these details
    since the dynptr needs to be located in multiple places outside the
    process_dynptr_func checks, hence once we know it's a PTR_TO_STACK, we
    need to enforce these checks in all places.
    
    Note that it is disallowed for unprivileged users to have a non-constant
    var_off, so this problem should only be possible to trigger from
    programs having CAP_PERFMON. However, its effects can vary.
    
    Without the fix, it is possible to replace the contents of the dynptr
    arbitrarily by making verifier mark different stack slots than actual
    location and then doing writes to the actual stack address of dynptr at
    runtime.
    
    Fixes: 97e03f52 ("bpf: Add verifier support for dynptrs")
    Acked-by: default avatarJoanne Koong <joannelkoong@gmail.com>
    Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
    Link: https://lore.kernel.org/r/20230121002241.2113993-3-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    79168a66
dynptr_fail.c 13.5 KB