• Alexei Starovoitov's avatar
    bpf: Introduce dynamic program extensions · be8704ff
    Alexei Starovoitov authored
    Introduce dynamic program extensions. The users can load additional BPF
    functions and replace global functions in previously loaded BPF programs while
    these programs are executing.
    
    Global functions are verified individually by the verifier based on their types only.
    Hence the global function in the new program which types match older function can
    safely replace that corresponding function.
    
    This new function/program is called 'an extension' of old program. At load time
    the verifier uses (attach_prog_fd, attach_btf_id) pair to identify the function
    to be replaced. The BPF program type is derived from the target program into
    extension program. Technically bpf_verifier_ops is copied from target program.
    The BPF_PROG_TYPE_EXT program type is a placeholder. It has empty verifier_ops.
    The extension program can call the same bpf helper functions as target program.
    Single BPF_PROG_TYPE_EXT type is used to extend XDP, SKB and all other program
    types. The verifier allows only one level of replacement. Meaning that the
    extension program cannot recursively extend an extension. That also means that
    the maximum stack size is increasing from 512 to 1024 bytes and maximum
    function nesting level from 8 to 16. The programs don't always consume that
    much. The stack usage is determined by the number of on-stack variables used by
    the program. The verifier could have enforced 512 limit for combined original
    plus extension program, but it makes for difficult user experience. The main
    use case for extensions is to provide generic mechanism to plug external
    programs into policy program or function call chaining.
    
    BPF trampoline is used to track both fentry/fexit and program extensions
    because both are using the same nop slot at the beginning of every BPF
    function. Attaching fentry/fexit to a function that was replaced is not
    allowed. The opposite is true as well. Replacing a function that currently
    being analyzed with fentry/fexit is not allowed. The executable page allocated
    by BPF trampoline is not used by program extensions. This inefficiency will be
    optimized in future patches.
    
    Function by function verification of global function supports scalars and
    pointer to context only. Hence program extensions are supported for such class
    of global functions only. In the future the verifier will be extended with
    support to pointers to structures, arrays with sizes, etc.
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Acked-by: default avatarAndrii Nakryiko <andriin@fb.com>
    Acked-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
    Link: https://lore.kernel.org/bpf/20200121005348.2769920-2-ast@kernel.org
    be8704ff
verifier.c 289 KB