• Kumar Kartikeya Dwivedi's avatar
    bpf: Disallow fentry/fexit/freplace for exception callbacks · fd548e1a
    Kumar Kartikeya Dwivedi authored
    During testing, it was discovered that extensions to exception callbacks
    had no checks, upon running a testcase, the kernel ended up running off
    the end of a program having final call as bpf_throw, and hitting int3
    instructions.
    
    The reason is that while the default exception callback would have reset
    the stack frame to return back to the main program's caller, the
    replacing extension program will simply return back to bpf_throw, which
    will instead return back to the program and the program will continue
    execution, now in an undefined state where anything could happen.
    
    The way to support extensions to an exception callback would be to mark
    the BPF_PROG_TYPE_EXT main subprog as an exception_cb, and prevent it
    from calling bpf_throw. This would make the JIT produce a prologue that
    restores saved registers and reset the stack frame. But let's not do
    that until there is a concrete use case for this, and simply disallow
    this for now.
    
    Similar issues will exist for fentry and fexit cases, where trampoline
    saves data on the stack when invoking exception callback, which however
    will then end up resetting the stack frame, and on return, the fexit
    program will never will invoked as the return address points to the main
    program's caller in the kernel. Instead of additional complexity and
    back and forth between the two stacks to enable such a use case, simply
    forbid it.
    
    One key point here to note is that currently X86_TAIL_CALL_OFFSET didn't
    require any modifications, even though we emit instructions before the
    corresponding endbr64 instruction. This is because we ensure that a main
    subprog never serves as an exception callback, and therefore the
    exception callback (which will be a global subprog) can never serve as
    the tail call target, eliminating any discrepancies. However, once we
    support a BPF_PROG_TYPE_EXT to also act as an exception callback, it
    will end up requiring change to the tail call offset to account for the
    extra instructions. For simplicitly, tail calls could be disabled for
    such targets.
    
    Noting the above, it appears better to wait for a concrete use case
    before choosing to permit extension programs to replace exception
    callbacks.
    
    As a precaution, we disable fentry and fexit for exception callbacks as
    well.
    Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
    Link: https://lore.kernel.org/r/20230912233214.1518551-13-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    fd548e1a
verifier.c 594 KB