• Martin KaFai Lau's avatar
    bpf: Add gen_epilogue to bpf_verifier_ops · 169c3176
    Martin KaFai Lau authored
    This patch adds a .gen_epilogue to the bpf_verifier_ops. It is similar
    to the existing .gen_prologue. Instead of allowing a subsystem
    to run code at the beginning of a bpf prog, it allows the subsystem
    to run code just before the bpf prog exit.
    
    One of the use case is to allow the upcoming bpf qdisc to ensure that
    the skb->dev is the same as the qdisc->dev_queue->dev. The bpf qdisc
    struct_ops implementation could either fix it up or drop the skb.
    Another use case could be in bpf_tcp_ca.c to enforce snd_cwnd
    has sane value (e.g. non zero).
    
    The epilogue can do the useful thing (like checking skb->dev) if it
    can access the bpf prog's ctx. Unlike prologue, r1 may not hold the
    ctx pointer. This patch saves the r1 in the stack if the .gen_epilogue
    has returned some instructions in the "epilogue_buf".
    
    The existing .gen_prologue is done in convert_ctx_accesses().
    The new .gen_epilogue is done in the convert_ctx_accesses() also.
    When it sees the (BPF_JMP | BPF_EXIT) instruction, it will be patched
    with the earlier generated "epilogue_buf". The epilogue patching is
    only done for the main prog.
    
    Only one epilogue will be patched to the main program. When the
    bpf prog has multiple BPF_EXIT instructions, a BPF_JA is used
    to goto the earlier patched epilogue. Majority of the archs
    support (BPF_JMP32 | BPF_JA): x86, arm, s390, risv64, loongarch,
    powerpc and arc. This patch keeps it simple and always
    use (BPF_JMP32 | BPF_JA). A new macro BPF_JMP32_A is added to
    generate the (BPF_JMP32 | BPF_JA) insn.
    Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
    Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
    Link: https://lore.kernel.org/r/20240829210833.388152-4-martin.lau@linux.devSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    169c3176
verifier.c 672 KB