• Andrii Nakryiko's avatar
    libbpf: only add BPF_F_MMAPABLE flag for data maps with global vars · 4fcac46c
    Andrii Nakryiko authored
    Teach libbpf to not add BPF_F_MMAPABLE flag unnecessarily for ARRAY maps
    that are backing data sections, if such data sections don't expose any
    variables to user-space. Exposed variables are those that have
    STB_GLOBAL or STB_WEAK ELF binding and correspond to BTF VAR's
    BTF_VAR_GLOBAL_ALLOCATED linkage.
    
    The overall idea is that if some data section doesn't have any variable that
    is exposed through BPF skeleton, then there is no reason to make such
    BPF array mmapable. Making BPF array mmapable is not a free no-op
    action, because BPF verifier doesn't allow users to put special objects
    (such as BPF spin locks, RB tree nodes, linked list nodes, kptrs, etc;
    anything that has a sensitive internal state that should not be modified
    arbitrarily from user space) into mmapable arrays, as there is no way to
    prevent user space from corrupting such sensitive state through direct
    memory access through memory-mapped region.
    
    By making sure that libbpf doesn't add BPF_F_MMAPABLE flag to BPF array
    maps corresponding to data sections that only have static variables
    (which are not supposed to be visible to user space according to libbpf
    and BPF skeleton rules), users now can have spinlocks, kptrs, etc in
    either default .bss/.data sections or custom .data.* sections (assuming
    there are no global variables in such sections).
    
    The only possible hiccup with this approach is the need to use global
    variables during BPF static linking, even if it's not intended to be
    shared with user space through BPF skeleton. To allow such scenarios,
    extend libbpf's STV_HIDDEN ELF visibility attribute handling to
    variables. Libbpf is already treating global hidden BPF subprograms as
    static subprograms and adjusts BTF accordingly to make BPF verifier
    verify such subprograms as static subprograms with preserving entire BPF
    verifier state between subprog calls. This patch teaches libbpf to treat
    global hidden variables as static ones and adjust BTF information
    accordingly as well. This allows to share variables between multiple
    object files during static linking, but still keep them internal to BPF
    program and not get them exposed through BPF skeleton.
    
    Note, that if the user has some advanced scenario where they absolutely
    need BPF_F_MMAPABLE flag on .data/.bss/.rodata BPF array map despite
    only having static variables, they still can achieve this by forcing it
    through explicit bpf_map__set_map_flags() API.
    Acked-by: default avatarStanislav Fomichev <sdf@google.com>
    Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Acked-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
    Link: https://lore.kernel.org/r/20221019002816.359650-3-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    4fcac46c
libbpf.c 328 KB