1. Jan 25, 2024
    • Andrii Nakryiko's avatar
      Merge branch 'bpf-token' · c8632acf
      Andrii Nakryiko authored
      Andrii Nakryiko says:
      
      ====================
      BPF token
      
      This patch set is a combination of three BPF token-related patch sets ([0],
      [1], [2]) with fixes ([3]) to kernel-side token_fd passing APIs incorporated
      into relevant patches, bpf_token_capable() changes requested by
      Christian Brauner, and necessary libbpf and BPF selftests side adjustments.
      
      This patch set introduces an ability to delegate a subset of BPF subsystem
      functionality from privileged system-wide daemon (e.g., systemd or any other
      container manager) through special mount options for userns-bound BPF FS to
      a *trusted* unprivileged application. Trust is the key here. This
      functionality is not about allowing unconditional unprivileged BPF usage.
      Establishing trust, though, is completely up to the discretion of respective
      privileged application that would create and mount a BPF FS instance with
      delegation enabled, as different production setups can and do achieve it
      through a combination of different means (signing, LSM, code reviews, etc),
      and it's undesirable and infeasible for kernel to enforce any particular way
      of validating trustworthiness of particular process.
      
      The main motivation for this work is a desire to enable containerized BPF
      applications to be used together with user namespaces. This is currently
      impossible, as CAP_BPF, required for BPF subsystem usage, cannot be namespaced
      or sandboxed, as a general rule. E.g., tracing BPF programs, thanks to BPF
      helpers like bpf_probe_read_kernel() and bpf_probe_read_user() can safely read
      arbitrary memory, and it's impossible to ensure that they only read memory of
      processes belonging to any given namespace. This means that it's impossible to
      have a mechanically verifiable namespace-aware CAP_BPF capability, and as such
      another mechanism to allow safe usage of BPF functionality is necessary.
      
      BPF FS delegation mount options and BPF token derived from such BPF FS instance
      is such a mechanism. Kernel makes no assumption about what "trusted"
      constitutes in any particular case, and it's up to specific privileged
      applications and their surrounding infrastructure to decide that. What kernel
      provides is a set of APIs to setup and mount special BPF FS instance and
      derive BPF tokens from it. BPF FS and BPF token are both bound to its owning
      userns and in such a way are constrained inside intended container. Users can
      then pass BPF token FD to privileged bpf() syscall commands, like BPF map
      creation and BPF program loading, to perform such operations without having
      init userns privileges.
      
      This version incorporates feedback and suggestions ([4]) received on earlier
      iterations of BPF token approach, and instead of allowing to create BPF tokens
      directly assuming capable(CAP_SYS_ADMIN), we instead enhance BPF FS to accept
      a few new delegation mount options. If these options are used and BPF FS itself
      is properly created, set up, and mounted inside the user namespaced container,
      user application is able to derive a BPF token object from BPF FS instance, and
      pass that token to bpf() syscall. As explained in patch #3, BPF token itself
      doesn't grant access to BPF functionality, but instead allows kernel to do
      namespaced capabilities checks (ns_capable() vs capable()) for CAP_BPF,
      CAP_PERFMON, CAP_NET_ADMIN, and CAP_SYS_ADMIN, as applicable. So it forms one
      half of a puzzle and allows container managers and sys admins to have safe and
      flexible configuration options: determining which containers get delegation of
      BPF functionality through BPF FS, and then which applications within such
      containers are allowed to perform bpf() commands, based on namespaces
      capabilities.
      
      Previous attempt at addressing this very same problem ([5]) attempted to
      utilize authoritative LSM approach, but was conclusively rejected by upstream
      LSM maintainers. BPF token concept is not changing anything about LSM
      approach, but can be combined with LSM hooks for very fine-grained security
      policy. Some ideas about making BPF token more convenient to use with LSM (in
      particular custom BPF LSM programs) was briefly described in recent LSF/MM/BPF
      2023 presentation ([6]). E.g., an ability to specify user-provided data
      (context), which in combination with BPF LSM would allow implementing a very
      dynamic and fine-granular custom security policies on top of BPF token. In the
      interest of minimizing API surface area and discussions this was relegated to
      follow up patches, as it's not essential to the fundamental concept of
      delegatable BPF token.
      
      It should be noted that BPF token is conceptually quite similar to the idea of
      /dev/bpf device file, proposed by Song a while ago ([7]). The biggest
      difference is the idea of using virtual anon_inode file to hold BPF token and
      allowing multiple independent instances of them, each (potentially) with its
      own set of restrictions. And also, crucially, BPF token approach is not using
      any special stateful task-scoped flags. Instead, bpf() syscall accepts
      token_fd parameters explicitly for each relevant BPF command. This addresses
      main concerns brought up during the /dev/bpf discussion, and fits better with
      overall BPF subsystem design.
      
      Second part of this patch set adds full support for BPF token in libbpf's BPF
      object high-level API. Good chunk of the changes rework libbpf feature
      detection internals, which are the most affected by BPF token presence.
      
      Besides internal refactorings, libbpf allows to pass location of BPF FS from
      which BPF token should be created by libbpf. This can be done explicitly though
      a new bpf_object_open_opts.bpf_token_path field. But we also add implicit BPF
      token creation logic to BPF object load step, even without any explicit
      involvement of the user. If the environment is setup properly, BPF token will
      be created transparently and used implicitly. This allows for all existing
      application to gain BPF token support by just linking with latest version of
      libbpf library. No source code modifications are required.  All that under
      assumption that privileged container management agent properly set up default
      BPF FS instance at /sys/bpf/fs to allow BPF token creation.
      
      libbpf adds support to override default BPF FS location for BPF token creation
      through LIBBPF_BPF_TOKEN_PATH envvar knowledge. This allows admins or container
      managers to mount BPF token-enabled BPF FS at non-standard location without the
      need to coordinate with applications.  LIBBPF_BPF_TOKEN_PATH can also be used
      to disable BPF token implicit creation by setting it to an empty value.
      
        [0] https://patchwork.kernel.org/project/netdevbpf/list/?series=805707&state=*
        [1] https://patchwork.kernel.org/project/netdevbpf/list/?series=810260&state=*
        [2] https://patchwork.kernel.org/project/netdevbpf/list/?series=809800&state=*
        [3] https://patchwork.kernel.org/project/netdevbpf/patch/20231219053150.336991-1-andrii@kernel.org/
        [4] https://lore.kernel.org/bpf/20230704-hochverdient-lehne-eeb9eeef785e@brauner/
        [5] https://lore.kernel.org/bpf/20230412043300.360803-1-andrii@kernel.org/
        [6] http://vger.kernel.org/bpfconf2023_material/Trusted_unprivileged_BPF_LSFMM2023.pdf
        [7] https://lore.kernel.org/bpf/20190627201923.2589391-2-songliubraving@fb.com/
      
      
      
      v1->v2:
        - disable BPF token creation in init userns, and simplify
          bpf_token_capable() logic (Christian);
        - use kzalloc/kfree instead of kvzalloc/kvfree (Linus);
        - few more selftest cases to validate LSM and BPF token interations.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      ====================
      
      Link: https://lore.kernel.org/r/20240124022127.2379740-1-andrii@kernel.org
      
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c8632acf
    • Andrii Nakryiko's avatar
      selftests/bpf: Incorporate LSM policy to token-based tests · 906ee42c
      Andrii Nakryiko authored
      
      
      Add tests for LSM interactions (both bpf_token_capable and bpf_token_cmd
      LSM hooks) with BPF token in bpf() subsystem. Now child process passes
      back token FD for parent to be able to do tests with token originating
      in "wrong" userns. But we also create token in initns and check that
      token LSMs don't accidentally reject BPF operations when capable()
      checks pass without BPF token.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-31-andrii@kernel.org
      906ee42c
    • Andrii Nakryiko's avatar
      selftests/bpf: Add tests for LIBBPF_BPF_TOKEN_PATH envvar · fadf5493
      Andrii Nakryiko authored
      
      
      Add new subtest validating LIBBPF_BPF_TOKEN_PATH envvar semantics.
      Extend existing test to validate that LIBBPF_BPF_TOKEN_PATH allows to
      disable implicit BPF token creation by setting envvar to empty string.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-30-andrii@kernel.org
      fadf5493
    • Andrii Nakryiko's avatar
      libbpf: Support BPF token path setting through LIBBPF_BPF_TOKEN_PATH envvar · cac270ad
      Andrii Nakryiko authored
      
      
      To allow external admin authority to override default BPF FS location
      (/sys/fs/bpf) for implicit BPF token creation, teach libbpf to recognize
      LIBBPF_BPF_TOKEN_PATH envvar. If it is specified and user application
      didn't explicitly specify bpf_token_path option, it will be treated
      exactly like bpf_token_path option, overriding default /sys/fs/bpf
      location and making BPF token mandatory.
      
      Suggested-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-29-andrii@kernel.org
      cac270ad
    • Andrii Nakryiko's avatar
      selftests/bpf: Add tests for BPF object load with implicit token · b73d08d1
      Andrii Nakryiko authored
      
      
      Add a test to validate libbpf's implicit BPF token creation from default
      BPF FS location (/sys/fs/bpf). Also validate that disabling this
      implicit BPF token creation works.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-28-andrii@kernel.org
      b73d08d1
    • Andrii Nakryiko's avatar
      selftests/bpf: Add BPF object loading tests with explicit token passing · d5baf0ca
      Andrii Nakryiko authored
      
      
      Add a few tests that attempt to load BPF object containing privileged
      map, program, and the one requiring mandatory BTF uploading into the
      kernel (to validate token FD propagation to BPF_BTF_LOAD command).
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-27-andrii@kernel.org
      d5baf0ca
    • Andrii Nakryiko's avatar
      libbpf: Wire up BPF token support at BPF object level · 6b434b61
      Andrii Nakryiko authored
      
      
      Add BPF token support to BPF object-level functionality.
      
      BPF token is supported by BPF object logic either as an explicitly
      provided BPF token from outside (through BPF FS path), or implicitly
      (unless prevented through bpf_object_open_opts).
      
      Implicit mode is assumed to be the most common one for user namespaced
      unprivileged workloads. The assumption is that privileged container
      manager sets up default BPF FS mount point at /sys/fs/bpf with BPF token
      delegation options (delegate_{cmds,maps,progs,attachs} mount options).
      BPF object during loading will attempt to create BPF token from
      /sys/fs/bpf location, and pass it for all relevant operations
      (currently, map creation, BTF load, and program load).
      
      In this implicit mode, if BPF token creation fails due to whatever
      reason (BPF FS is not mounted, or kernel doesn't support BPF token,
      etc), this is not considered an error. BPF object loading sequence will
      proceed with no BPF token.
      
      In explicit BPF token mode, user provides explicitly custom BPF FS mount
      point path. In such case, BPF object will attempt to create BPF token
      from provided BPF FS location. If BPF token creation fails, that is
      considered a critical error and BPF object load fails with an error.
      
      Libbpf provides a way to disable implicit BPF token creation, if it
      causes any troubles (BPF token is designed to be completely optional and
      shouldn't cause any problems even if provided, but in the world of BPF
      LSM, custom security logic can be installed that might change outcome
      depending on the presence of BPF token). To disable libbpf's default BPF
      token creation behavior user should provide either invalid BPF token FD
      (negative), or empty bpf_token_path option.
      
      BPF token presence can influence libbpf's feature probing, so if BPF
      object has associated BPF token, feature probing is instructed to use
      BPF object-specific feature detection cache and token FD.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-26-andrii@kernel.org
      6b434b61
    • Andrii Nakryiko's avatar
      libbpf: Wire up token_fd into feature probing logic · f3dcee93
      Andrii Nakryiko authored
      
      
      Adjust feature probing callbacks to take into account optional token_fd.
      In unprivileged contexts, some feature detectors would fail to detect
      kernel support just because BPF program, BPF map, or BTF object can't be
      loaded due to privileged nature of those operations. So when BPF object
      is loaded with BPF token, this token should be used for feature probing.
      
      This patch is setting support for this scenario, but we don't yet pass
      non-zero token FD. This will be added in the next patch.
      
      We also switched BPF cookie detector from using kprobe program to
      tracepoint one, as tracepoint is somewhat less dangerous BPF program
      type and has higher likelihood of being allowed through BPF token in the
      future. This change has no effect on detection behavior.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-25-andrii@kernel.org
      f3dcee93
    • Andrii Nakryiko's avatar
      libbpf: Move feature detection code into its own file · 05f9cdd5
      Andrii Nakryiko authored
      
      
      It's quite a lot of well isolated code, so it seems like a good
      candidate to move it out of libbpf.c to reduce its size.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-24-andrii@kernel.org
      05f9cdd5
    • Andrii Nakryiko's avatar
      libbpf: Further decouple feature checking logic from bpf_object · d6dd1d49
      Andrii Nakryiko authored
      
      
      Add feat_supported() helper that accepts feature cache instead of
      bpf_object. This allows low-level code in bpf.c to not know or care
      about higher-level concept of bpf_object, yet it will be able to utilize
      custom feature checking in cases where BPF token might influence the
      outcome.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-23-andrii@kernel.org
      d6dd1d49
    • Andrii Nakryiko's avatar
      libbpf: Split feature detectors definitions from cached results · ea4d5873
      Andrii Nakryiko authored
      
      
      Split a list of supported feature detectors with their corresponding
      callbacks from actual cached supported/missing values. This will allow
      to have more flexible per-token or per-object feature detectors in
      subsequent refactorings.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-22-andrii@kernel.org
      ea4d5873
    • Andrii Nakryiko's avatar
      selftests/bpf: Utilize string values for delegate_xxx mount options · 0350f9d9
      Andrii Nakryiko authored
      
      
      Use both hex-based and string-based way to specify delegate mount
      options for BPF FS.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-21-andrii@kernel.org
      0350f9d9
    • Andrii Nakryiko's avatar
      bpf: Support symbolic BPF FS delegation mount options · 6c1752e0
      Andrii Nakryiko authored
      
      
      Besides already supported special "any" value and hex bit mask, support
      string-based parsing of delegation masks based on exact enumerator
      names. Utilize BTF information of `enum bpf_cmd`, `enum bpf_map_type`,
      `enum bpf_prog_type`, and `enum bpf_attach_type` types to find supported
      symbolic names (ignoring __MAX_xxx guard values and stripping repetitive
      prefixes like BPF_ for cmd and attach types, BPF_MAP_TYPE_ for maps, and
      BPF_PROG_TYPE_ for prog types). The case doesn't matter, but it is
      normalized to lower case in mount option output. So "PROG_LOAD",
      "prog_load", and "MAP_create" are all valid values to specify for
      delegate_cmds options, "array" is among supported for map types, etc.
      
      Besides supporting string values, we also support multiple values
      specified at the same time, using colon (':') separator.
      
      There are corresponding changes on bpf_show_options side to use known
      values to print them in human-readable format, falling back to hex mask
      printing, if there are any unrecognized bits. This shouldn't be
      necessary when enum BTF information is present, but in general we should
      always be able to fall back to this even if kernel was built without BTF.
      As mentioned, emitted symbolic names are normalized to be all lower case.
      
      Example below shows various ways to specify delegate_cmds options
      through mount command and how mount options are printed back:
      
      12/14 14:39:07.604
      vmuser@archvm:~/local/linux/tools/testing/selftests/bpf
      $ mount | rg token
      
        $ sudo mkdir -p /sys/fs/bpf/token
        $ sudo mount -t bpf bpffs /sys/fs/bpf/token \
                     -o delegate_cmds=prog_load:MAP_CREATE \
                     -o delegate_progs=kprobe \
                     -o delegate_attachs=xdp
        $ mount | grep token
        bpffs on /sys/fs/bpf/token type bpf (rw,relatime,delegate_cmds=map_create:prog_load,delegate_progs=kprobe,delegate_attachs=xdp)
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-20-andrii@kernel.org
      6c1752e0
    • Andrii Nakryiko's avatar
      bpf: Fail BPF_TOKEN_CREATE if no delegation option was set on BPF FS · aeaa97b0
      Andrii Nakryiko authored
      
      
      It's quite confusing in practice when it's possible to successfully
      create a BPF token from BPF FS that didn't have any of delegate_xxx
      mount options set up. While it's not wrong, it's actually more
      meaningful to reject BPF_TOKEN_CREATE with specific error code (-ENOENT)
      to let user-space know that no token delegation is setup up.
      
      So, instead of creating empty BPF token that will be always ignored
      because it doesn't have any of the allow_xxx bits set, reject it with
      -ENOENT. If we ever need empty BPF token to be possible, we can support
      that with extra flag passed into BPF_TOKEN_CREATE.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarChristian Brauner <brauner@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-19-andrii@kernel.org
      aeaa97b0
    • Andrii Nakryiko's avatar
      bpf,selinux: Allocate bpf_security_struct per BPF token · 0054493e
      Andrii Nakryiko authored
      
      
      Utilize newly added bpf_token_create/bpf_token_free LSM hooks to
      allocate struct bpf_security_struct for each BPF token object in
      SELinux. This just follows similar pattern for BPF prog and map.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-18-andrii@kernel.org
      0054493e
    • Andrii Nakryiko's avatar
      selftests/bpf: Add BPF token-enabled tests · fcb9597f
      Andrii Nakryiko authored
      Add a selftest that attempts to conceptually replicate intended BPF
      token use cases inside user namespaced container.
      
      Child process is forked. It is then put into its own userns and mountns.
      Child creates BPF FS context object. This ensures child userns is
      captured as the owning userns for this instance of BPF FS. Given setting
      delegation mount options is privileged operation, we ensure that child
      cannot set them.
      
      This context is passed back to privileged parent process through Unix
      socket, where parent sets up delegation options, creates, and mounts it
      as a detached mount. This mount FD is passed back to the child to be
      used for BPF token creation, which allows otherwise privileged BPF
      operations to succeed inside userns.
      
      We validate that all of token-enabled privileged commands (BPF_BTF_LOAD,
      BPF_MAP_CREATE, and BPF_PROG_LOAD) work as intended. They should only
      succeed inside the userns if a) BPF token is provided with proper
      allowed sets of commands and types; and b) namespaces CAP_BPF and other
      privileges are set. Lacking a) or b) should lead to -EPERM failures.
      
      Based on suggested workflow by Christian Brauner ([0]).
      
        [0] https://lore.kernel.org/bpf/20230704-hochverdient-lehne-eeb9eeef785e@brauner/
      
      
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-17-andrii@kernel.org
      fcb9597f
    • Andrii Nakryiko's avatar
      404cbc14
    • Andrii Nakryiko's avatar
      libbpf: Add BPF token support to bpf_btf_load() API · a3d63e85
      Andrii Nakryiko authored
      
      
      Allow user to specify token_fd for bpf_btf_load() API that wraps
      kernel's BPF_BTF_LOAD command. This allows loading BTF from unprivileged
      process as long as it has BPF token allowing BPF_BTF_LOAD command, which
      can be created and delegated by privileged process.
      
      Wire through new btf_flags as well, so that user can provide
      BPF_F_TOKEN_FD flag, if necessary.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-15-andrii@kernel.org
      a3d63e85
    • Andrii Nakryiko's avatar
      libbpf: Add BPF token support to bpf_map_create() API · 364f8483
      Andrii Nakryiko authored
      
      
      Add ability to provide token_fd for BPF_MAP_CREATE command through
      bpf_map_create() API.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-14-andrii@kernel.org
      364f8483
    • Andrii Nakryiko's avatar
      libbpf: Add bpf_token_create() API · 639ecd7d
      Andrii Nakryiko authored
      
      
      Add low-level wrapper API for BPF_TOKEN_CREATE command in bpf() syscall.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-13-andrii@kernel.org
      639ecd7d
    • Andrii Nakryiko's avatar
      bpf,lsm: Add BPF token LSM hooks · f568a3d4
      Andrii Nakryiko authored
      
      
      Wire up bpf_token_create and bpf_token_free LSM hooks, which allow to
      allocate LSM security blob (we add `void *security` field to struct
      bpf_token for that), but also control who can instantiate BPF token.
      This follows existing pattern for BPF map and BPF prog.
      
      Also add security_bpf_token_allow_cmd() and security_bpf_token_capable()
      LSM hooks that allow LSM implementation to control and negate (if
      necessary) BPF token's delegation of a specific bpf_cmd and capability,
      respectively.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarPaul Moore <paul@paul-moore.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-12-andrii@kernel.org
      f568a3d4
    • Andrii Nakryiko's avatar
      bpf,lsm: Refactor bpf_map_alloc/bpf_map_free LSM hooks · a2431c7e
      Andrii Nakryiko authored
      
      
      Similarly to bpf_prog_alloc LSM hook, rename and extend bpf_map_alloc
      hook into bpf_map_create, taking not just struct bpf_map, but also
      bpf_attr and bpf_token, to give a fuller context to LSMs.
      
      Unlike bpf_prog_alloc, there is no need to move the hook around, as it
      currently is firing right before allocating BPF map ID and FD, which
      seems to be a sweet spot.
      
      But like bpf_prog_alloc/bpf_prog_free combo, make sure that bpf_map_free
      LSM hook is called even if bpf_map_create hook returned error, as if few
      LSMs are combined together it could be that one LSM successfully
      allocated security blob for its needs, while subsequent LSM rejected BPF
      map creation. The former LSM would still need to free up LSM blob, so we
      need to ensure security_bpf_map_free() is called regardless of the
      outcome.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarPaul Moore <paul@paul-moore.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-11-andrii@kernel.org
      a2431c7e
    • Andrii Nakryiko's avatar
      bpf,lsm: Refactor bpf_prog_alloc/bpf_prog_free LSM hooks · 1b67772e
      Andrii Nakryiko authored
      Based on upstream discussion ([0]), rework existing
      bpf_prog_alloc_security LSM hook. Rename it to bpf_prog_load and instead
      of passing bpf_prog_aux, pass proper bpf_prog pointer for a full BPF
      program struct. Also, we pass bpf_attr union with all the user-provided
      arguments for BPF_PROG_LOAD command.  This will give LSMs as much
      information as we can basically provide.
      
      The hook is also BPF token-aware now, and optional bpf_token struct is
      passed as a third argument. bpf_prog_load LSM hook is called after
      a bunch of sanity checks were performed, bpf_prog and bpf_prog_aux were
      allocated and filled out, but right before performing full-fledged BPF
      verification step.
      
      bpf_prog_free LSM hook is now accepting struct bpf_prog argument, for
      consistency. SELinux code is adjusted to all new names, types, and
      signatures.
      
      Note, given that bpf_prog_load (previously bpf_prog_alloc) hook can be
      used by some LSMs to allocate extra security blob, but also by other
      LSMs to reject BPF program loading, we need to make sure that
      bpf_prog_free LSM hook is called after bpf_prog_load/bpf_prog_alloc one
      *even* if the hook itself returned error. If we don't do that, we run
      the risk of leaking memory. This seems to be possible today when
      combining SELinux and BPF LSM, as one example, depending on their
      relative ordering.
      
      Also, for BPF LSM setup, add bpf_prog_load and bpf_prog_free to
      sleepable LSM hooks list, as they are both executed in sleepable
      context. Also drop bpf_prog_load hook from untrusted, as there is no
      issue with refcount or anything else anymore, that originally forced us
      to add it to untrusted list in c0c852dd ("bpf: Do not mark certain LSM
      hook arguments as trusted"). We now trigger this hook much later and it
      should not be an issue anymore.
      
        [0] https://lore.kernel.org/bpf/9fe88aef7deabbe87d3fc38c4aea3c69.paul@paul-moore.com/
      
      
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarPaul Moore <paul@paul-moore.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-10-andrii@kernel.org
      1b67772e
    • Andrii Nakryiko's avatar
      bpf: Consistently use BPF token throughout BPF verifier logic · d79a3549
      Andrii Nakryiko authored
      
      
      Remove remaining direct queries to perfmon_capable() and bpf_capable()
      in BPF verifier logic and instead use BPF token (if available) to make
      decisions about privileges.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-9-andrii@kernel.org
      d79a3549
    • Andrii Nakryiko's avatar
      bpf: Take into account BPF token when fetching helper protos · bbc1d247
      Andrii Nakryiko authored
      
      
      Instead of performing unconditional system-wide bpf_capable() and
      perfmon_capable() calls inside bpf_base_func_proto() function (and other
      similar ones) to determine eligibility of a given BPF helper for a given
      program, use previously recorded BPF token during BPF_PROG_LOAD command
      handling to inform the decision.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-8-andrii@kernel.org
      bbc1d247
    • Andrii Nakryiko's avatar
      bpf: Add BPF token support to BPF_PROG_LOAD command · caf8f28e
      Andrii Nakryiko authored
      
      
      Add basic support of BPF token to BPF_PROG_LOAD. BPF_F_TOKEN_FD flag
      should be set in prog_flags field when providing prog_token_fd.
      
      Wire through a set of allowed BPF program types and attach types,
      derived from BPF FS at BPF token creation time. Then make sure we
      perform bpf_token_capable() checks everywhere where it's relevant.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-7-andrii@kernel.org
      caf8f28e
    • Andrii Nakryiko's avatar
      bpf: Add BPF token support to BPF_BTF_LOAD command · 9ea7c4bf
      Andrii Nakryiko authored
      
      
      Accept BPF token FD in BPF_BTF_LOAD command to allow BTF data loading
      through delegated BPF token. BPF_F_TOKEN_FD flag has to be specified
      when passing BPF token FD. Given BPF_BTF_LOAD command didn't have flags
      field before, we also add btf_flags field.
      
      BTF loading is a pretty straightforward operation, so as long as BPF
      token is created with allow_cmds granting BPF_BTF_LOAD command, kernel
      proceeds to parsing BTF data and creating BTF object.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-6-andrii@kernel.org
      9ea7c4bf
    • Andrii Nakryiko's avatar
      bpf: Add BPF token support to BPF_MAP_CREATE command · a177fc2b
      Andrii Nakryiko authored
      
      
      Allow providing token_fd for BPF_MAP_CREATE command to allow controlled
      BPF map creation from unprivileged process through delegated BPF token.
      New BPF_F_TOKEN_FD flag is added to specify together with BPF token FD
      for BPF_MAP_CREATE command.
      
      Wire through a set of allowed BPF map types to BPF token, derived from
      BPF FS at BPF token creation time. This, in combination with allowed_cmds
      allows to create a narrowly-focused BPF token (controlled by privileged
      agent) with a restrictive set of BPF maps that application can attempt
      to create.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-5-andrii@kernel.org
      a177fc2b
    • Andrii Nakryiko's avatar
      bpf: Introduce BPF token object · 35f96de0
      Andrii Nakryiko authored
      
      
      Add new kind of BPF kernel object, BPF token. BPF token is meant to
      allow delegating privileged BPF functionality, like loading a BPF
      program or creating a BPF map, from privileged process to a *trusted*
      unprivileged process, all while having a good amount of control over which
      privileged operations could be performed using provided BPF token.
      
      This is achieved through mounting BPF FS instance with extra delegation
      mount options, which determine what operations are delegatable, and also
      constraining it to the owning user namespace (as mentioned in the
      previous patch).
      
      BPF token itself is just a derivative from BPF FS and can be created
      through a new bpf() syscall command, BPF_TOKEN_CREATE, which accepts BPF
      FS FD, which can be attained through open() API by opening BPF FS mount
      point. Currently, BPF token "inherits" delegated command, map types,
      prog type, and attach type bit sets from BPF FS as is. In the future,
      having an BPF token as a separate object with its own FD, we can allow
      to further restrict BPF token's allowable set of things either at the
      creation time or after the fact, allowing the process to guard itself
      further from unintentionally trying to load undesired kind of BPF
      programs. But for now we keep things simple and just copy bit sets as is.
      
      When BPF token is created from BPF FS mount, we take reference to the
      BPF super block's owning user namespace, and then use that namespace for
      checking all the {CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, CAP_SYS_ADMIN}
      capabilities that are normally only checked against init userns (using
      capable()), but now we check them using ns_capable() instead (if BPF
      token is provided). See bpf_token_capable() for details.
      
      Such setup means that BPF token in itself is not sufficient to grant BPF
      functionality. User namespaced process has to *also* have necessary
      combination of capabilities inside that user namespace. So while
      previously CAP_BPF was useless when granted within user namespace, now
      it gains a meaning and allows container managers and sys admins to have
      a flexible control over which processes can and need to use BPF
      functionality within the user namespace (i.e., container in practice).
      And BPF FS delegation mount options and derived BPF tokens serve as
      a per-container "flag" to grant overall ability to use bpf() (plus further
      restrict on which parts of bpf() syscalls are treated as namespaced).
      
      Note also, BPF_TOKEN_CREATE command itself requires ns_capable(CAP_BPF)
      within the BPF FS owning user namespace, rounding up the ns_capable()
      story of BPF token. Also creating BPF token in init user namespace is
      currently not supported, given BPF token doesn't have any effect in init
      user namespace anyways.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarChristian Brauner <brauner@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-4-andrii@kernel.org
      35f96de0
    • Andrii Nakryiko's avatar
      bpf: Add BPF token delegation mount options to BPF FS · 6fe01d3c
      Andrii Nakryiko authored
      Add few new mount options to BPF FS that allow to specify that a given
      BPF FS instance allows creation of BPF token (added in the next patch),
      and what sort of operations are allowed under BPF token. As such, we get
      4 new mount options, each is a bit mask
        - `delegate_cmds` allow to specify which bpf() syscall commands are
          allowed with BPF token derived from this BPF FS instance;
        - if BPF_MAP_CREATE command is allowed, `delegate_maps` specifies
          a set of allowable BPF map types that could be created with BPF token;
        - if BPF_PROG_LOAD command is allowed, `delegate_progs` specifies
          a set of allowable BPF program types that could be loaded with BPF token;
        - if BPF_PROG_LOAD command is allowed, `delegate_attachs` specifies
          a set of allowable BPF program attach types that could be loaded with
          BPF token; delegate_progs and delegate_attachs are meant to be used
          together, as full BPF program type is, in general, determined
          through both program type and program attach type.
      
      Currently, these mount options accept the following forms of values:
        - a special value "any", that enables all possible values of a given
        bit set;
        - numeric value (decimal or hexadecimal, determined by kernel
        automatically) that specifies a bit mask value directly;
        - all the values for a given mount option are combined, if specified
        multiple times. E.g., `mount -t bpf nodev /path/to/mount -o
        delegate_maps=0x1 -o delegate_maps=0x2` will result in a combined 0x3
        mask.
      
      Ideally, more convenient (for humans) symbolic form derived from
      corresponding UAPI enums would be accepted (e.g., `-o
      delegate_progs=kprobe|tracepoint`) and I intend to implement this, but
      it requires a bunch of UAPI header churn, so I postponed it until this
      feature lands upstream or at least there is a definite consensus that
      this feature is acceptable and is going to make it, just to minimize
      amount of wasted effort and not increase amount of non-essential code to
      be reviewed.
      
      Attentive reader will notice that BPF FS is now marked as
      FS_USERNS_MOUNT, which theoretically makes it mountable inside non-init
      user namespace as long as the process has sufficient *namespaced*
      capabilities within that user namespace. But in reality we still
      restrict BPF FS to be mountable only by processes with CAP_SYS_ADMIN *in
      init userns* (extra check in bpf_fill_super()). FS_USERNS_MOUNT is added
      to allow creating BPF FS context object (i.e., fsopen("bpf")) from
      inside unprivileged process inside non-init userns, to capture that
      userns as the owning userns. It will still be required to pass this
      context object back to privileged process to instantiate and mount it.
      
      This manipulation is important, because capturing non-init userns as the
      owning userns of BPF FS instance (super block) allows to use that userns
      to constraint BPF token to that userns later on (see next patch). So
      creating BPF FS with delegation inside unprivileged userns will restrict
      derived BPF token objects to only "work" inside that intended userns,
      making it scoped to a intended "container". Also, setting these
      delegation options requires capable(CAP_SYS_ADMIN), so unprivileged
      process cannot set this up without involvement of a privileged process.
      
      There is a set of selftests at the end of the patch set that simulates
      this sequence of steps and validates that everything works as intended.
      But careful review is requested to make sure there are no missed gaps in
      the implementation and testing.
      
      This somewhat subtle set of aspects is the result of previous
      discussions ([0]) about various user namespace implications and
      interactions with BPF token functionality and is necessary to contain
      BPF token inside intended user namespace.
      
        [0] https://lore.kernel.org/bpf/20230704-hochverdient-lehne-eeb9eeef785e@brauner/
      
      
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarChristian Brauner <brauner@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-3-andrii@kernel.org
      6fe01d3c
    • Andrii Nakryiko's avatar
      bpf: Align CAP_NET_ADMIN checks with bpf_capable() approach · ed1ad5a7
      Andrii Nakryiko authored
      
      
      Within BPF syscall handling code CAP_NET_ADMIN checks stand out a bit
      compared to CAP_BPF and CAP_PERFMON checks. For the latter, CAP_BPF or
      CAP_PERFMON are checked first, but if they are not set, CAP_SYS_ADMIN
      takes over and grants whatever part of BPF syscall is required.
      
      Similar kind of checks that involve CAP_NET_ADMIN are not so consistent.
      One out of four uses does follow CAP_BPF/CAP_PERFMON model: during
      BPF_PROG_LOAD, if the type of BPF program is "network-related" either
      CAP_NET_ADMIN or CAP_SYS_ADMIN is required to proceed.
      
      But in three other cases CAP_NET_ADMIN is required even if CAP_SYS_ADMIN
      is set:
        - when creating DEVMAP/XDKMAP/CPU_MAP maps;
        - when attaching CGROUP_SKB programs;
        - when handling BPF_PROG_QUERY command.
      
      This patch is changing the latter three cases to follow BPF_PROG_LOAD
      model, that is allowing to proceed under either CAP_NET_ADMIN or
      CAP_SYS_ADMIN.
      
      This also makes it cleaner in subsequent BPF token patches to switch
      wholesomely to a generic bpf_token_capable(int cap) check, that always
      falls back to CAP_SYS_ADMIN if requested capability is missing.
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Link: https://lore.kernel.org/bpf/20240124022127.2379740-2-andrii@kernel.org
      ed1ad5a7
    • Martin KaFai Lau's avatar
      libbpf: Ensure undefined bpf_attr field stays 0 · c9f11556
      Martin KaFai Lau authored
      The commit 9e926acd ("libbpf: Find correct module BTFs for struct_ops maps and progs.")
      sets a newly added field (value_type_btf_obj_fd) to -1 in libbpf when
      the caller of the libbpf's bpf_map_create did not define this field by
      passing a NULL "opts" or passing in a "opts" that does not cover this
      new field. OPT_HAS(opts, field) is used to decide if the field is
      defined or not:
      
      	((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
      
      Once OPTS_HAS decided the field is not defined, that field should
      be set to 0. For this particular new field (value_type_btf_obj_fd),
      its corresponding map_flags "BPF_F_VTYPE_BTF_OBJ_FD" is not set.
      Thus, the kernel does not treat it as an fd field.
      
      Fixes: 9e926acd
      
       ("libbpf: Find correct module BTFs for struct_ops maps and progs.")
      Reported-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20240124224418.2905133-1-martin.lau@linux.dev
      
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c9f11556
    • Martin KaFai Lau's avatar
      selftests/bpf: Wait for the netstamp_needed_key static key to be turned on · ce6f6cff
      Martin KaFai Lau authored
      After the previous patch that speeded up the test (by avoiding neigh
      discovery in IPv6), the BPF CI occasionally hits this error:
      
      rcv tstamp unexpected pkt rcv tstamp: actual 0 == expected 0
      
      The test complains about the cmsg returned from the recvmsg() does not
      have the rcv timestamp. Setting skb->tstamp or not is
      controlled by a kernel static key "netstamp_needed_key". The static
      key is enabled whenever this is at least one sk with the SOCK_TIMESTAMP
      set.
      
      The test_redirect_dtime does use setsockopt() to turn on
      the SOCK_TIMESTAMP for the reading sk. In the kernel
      net_enable_timestamp() has a delay to enable the "netstamp_needed_key"
      when CONFIG_JUMP_LABEL is set. This potential delay is the likely reason
      for packet missing rcv timestamp occasionally.
      
      This patch is to create udp sockets with SOCK_TIMESTAMP set.
      It sends and receives some packets until the received packet
      has a rcv timestamp. It currently retries at most 5 times with 1s
      in between. This should be enough to wait for the "netstamp_needed_key".
      It then holds on to the socket and only closes it at the end of the test.
      This guarantees that the test has the "netstamp_needed_key" key turned
      on from the beginning.
      
      To simplify the udp sockets setup, they are sending/receiving packets
      in the same netns (ns_dst is used) and communicate over the "lo" dev.
      Hence, the patch enables the "lo" dev in the ns_dst.
      
      Fixes: c803475f
      
       ("bpf: selftests: test skb->tstamp in redirect_neigh")
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20240120060518.3604920-2-martin.lau@linux.dev
      ce6f6cff
    • Martin KaFai Lau's avatar
      selftests/bpf: Fix the flaky tc_redirect_dtime test · 177f1d08
      Martin KaFai Lau authored
      BPF CI has been reporting the tc_redirect_dtime test failing
      from time to time:
      
      test_inet_dtime:PASS:setns src 0 nsec
      (network_helpers.c:253: errno: No route to host) Failed to connect to server
      close_netns:PASS:setns 0 nsec
      test_inet_dtime:FAIL:connect_to_fd unexpected connect_to_fd: actual -1 < expected 0
      test_tcp_clear_dtime:PASS:tcp ip6 clear dtime ingress_fwdns_p100 0 nsec
      
      The connect_to_fd failure (EHOSTUNREACH) is from the
      test_tcp_clear_dtime() test and it is the very first IPv6 traffic
      after setting up all the links, addresses, and routes.
      
      The symptom is this first connect() is always slow. In my setup, it
      could take ~3s.
      
      After some tracing and tcpdump, the slowness is mostly spent in
      the neighbor solicitation in the "ns_fwd" namespace while
      the "ns_src" and "ns_dst" are fine.
      
      I forced the kernel to drop the neighbor solicitation messages.
      I can then reproduce EHOSTUNREACH. What actually happen could be:
      - the neighbor advertisement came back a little slow.
      - the "ns_fwd" namespace concluded a neighbor discovery failure
        and triggered the ndisc_error_report() => ip6_link_failure() =>
        icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0)
      - the client's connect() reports EHOSTUNREACH after receiving
        the ICMPV6_DEST_UNREACH message.
      
      The neigh table of both "ns_src" and "ns_dst" namespace has already
      been manually populated but not the "ns_fwd" namespace. This patch
      fixes it by manually populating the neigh table also in the "ns_fwd"
      namespace.
      
      Although the namespace configuration part had been existed before
      the tc_redirect_dtime test, still Fixes-tagging the patch when
      the tc_redirect_dtime test was added since it is the only test
      hitting it so far.
      
      Fixes: c803475f
      
       ("bpf: selftests: test skb->tstamp in redirect_neigh")
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20240120060518.3604920-1-martin.lau@linux.dev
      177f1d08
  2. Jan 24, 2024
    • Dima Tisnek's avatar
      libbpf: Correct bpf_core_read.h comment wrt bpf_core_relo struct · d47b9f68
      Dima Tisnek authored
      Past commit ([0]) removed the last vestiges of struct bpf_field_reloc,
      it's called struct bpf_core_relo now.
      
        [0] 28b93c64
      
       ("libbpf: Clean up and improve CO-RE reloc logging")
      
      Signed-off-by: default avatarDima Tisnek <dimaqq@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarYonghong Song <yonghong.song@linux.dev>
      Link: https://lore.kernel.org/bpf/20240121060126.15650-1-dimaqq@gmail.com
      d47b9f68
    • Andrii Nakryiko's avatar
      Merge branch 'skip-callback-tests-if-jit-is-disabled-in-test_verifier' · 32749605
      Andrii Nakryiko authored
      Tiezhu Yang says:
      
      ====================
      Skip callback tests if jit is disabled in test_verifier
      
      Thanks very much for the feedbacks from Eduard, John, Jiri, Daniel,
      Hou Tao, Song Liu and Andrii.
      
      v7:
        -- Add an explicit flag F_NEEDS_JIT_ENABLED for checking,
           thanks Andrii.
      
      v6:
        -- Copy insn_is_pseudo_func() into testing_helpers,
           thanks Andrii.
      
      v5:
        -- Reuse is_ldimm64_insn() and insn_is_pseudo_func(),
           thanks Song Liu.
      
      v4:
        -- Move the not-allowed-checking into "if (expected_ret ...)"
           block, thanks Hou Tao.
        -- Do some small changes to avoid checkpatch warning
           about "line length exceeds 100 columns".
      
      v3:
        -- Rebase on the latest bpf-next tree.
        -- Address the review comments by Hou Tao,
           remove the second argument "0" of open(),
           check only once whether jit is disabled,
           check fd_prog, saved_errno and jit_disabled to skip.
      ====================
      
      Link: https://lore.kernel.org/r/20240123090351.2207-1-yangtiezhu@loongson.cn
      
      
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      32749605
    • Tiezhu Yang's avatar
      selftests/bpf: Skip callback tests if jit is disabled in test_verifier · 0b50478f
      Tiezhu Yang authored
      
      
      If CONFIG_BPF_JIT_ALWAYS_ON is not set and bpf_jit_enable is 0, there
      exist 6 failed tests.
      
        [root@linux bpf]# echo 0 > /proc/sys/net/core/bpf_jit_enable
        [root@linux bpf]# echo 0 > /proc/sys/kernel/unprivileged_bpf_disabled
        [root@linux bpf]# ./test_verifier | grep FAIL
        #106/p inline simple bpf_loop call FAIL
        #107/p don't inline bpf_loop call, flags non-zero FAIL
        #108/p don't inline bpf_loop call, callback non-constant FAIL
        #109/p bpf_loop_inline and a dead func FAIL
        #110/p bpf_loop_inline stack locations for loop vars FAIL
        #111/p inline bpf_loop call in a big program FAIL
        Summary: 768 PASSED, 15 SKIPPED, 6 FAILED
      
      The test log shows that callbacks are not allowed in non-JITed programs,
      interpreter doesn't support them yet, thus these tests should be skipped
      if jit is disabled.
      
      Add an explicit flag F_NEEDS_JIT_ENABLED to those tests to mark that they
      require JIT enabled in bpf_loop_inline.c, check the flag and jit_disabled
      at the beginning of do_test_single() to handle this case.
      
      With this patch:
      
        [root@linux bpf]# echo 0 > /proc/sys/net/core/bpf_jit_enable
        [root@linux bpf]# echo 0 > /proc/sys/kernel/unprivileged_bpf_disabled
        [root@linux bpf]# ./test_verifier | grep FAIL
        Summary: 768 PASSED, 21 SKIPPED, 0 FAILED
      
      Suggested-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20240123090351.2207-3-yangtiezhu@loongson.cn
      0b50478f
    • Tiezhu Yang's avatar
      selftests/bpf: Move is_jit_enabled() into testing_helpers · 15b4f88d
      Tiezhu Yang authored
      
      
      Currently, is_jit_enabled() is only used in test_progs, move it into
      testing_helpers so that it can be used in test_verifier. While at it,
      remove the second argument "0" of open() as Hou Tao suggested.
      
      Signed-off-by: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarHou Tao <houtao1@huawei.com>
      Acked-by: default avatarSong Liu <song@kernel.org>
      Link: https://lore.kernel.org/bpf/20240123090351.2207-2-yangtiezhu@loongson.cn
      15b4f88d
    • Martin KaFai Lau's avatar
      Merge branch 'Registrating struct_ops types from modules' · 8b593021
      Martin KaFai Lau authored
      Kui-Feng Lee says:
      
      ====================
      Given the current constraints of the current implementation,
      struct_ops cannot be registered dynamically. This presents a
      significant limitation for modules like coming fuse-bpf, which seeks
      to implement a new struct_ops type. To address this issue, a new API
      is introduced that allows the registration of new struct_ops types
      from modules.
      
      Previously, struct_ops types were defined in bpf_struct_ops_types.h
      and collected as a static array. The new API lets callers add new
      struct_ops types dynamically. The static array has been removed and
      replaced by the per-btf struct_ops_tab.
      
      The struct_ops subsystem relies on BTF to determine the layout of
      values in a struct_ops map and identify the subsystem that the
      struct_ops map registers to. However, the kernel BTF does not include
      the type information of struct_ops types defined by a module. The
      struct_ops subsystem requires knowledge of the corresponding module
      for a given struct_ops map and the utilization of BTF information from
      that module. We empower libbpf to determine the correct module for
      accessing the BTF information and pass an identity (FD) of the module
      btf to the kernel. The kernel looks up type information and registered
      struct_ops types directly from the given btf.
      
      If a module exits while one or more struct_ops maps still refer to a
      struct_ops type defined by the module, it can lead to unforeseen
      complications. Therefore, it is crucial to ensure that a module
      remains intact as long as any struct_ops map is still linked to a
      struct_ops type defined by the module. To achieve this, every
      struct_ops map holds a reference to the module while being registered.
      
      Changes from v16:
      
       - Fix unnecessary bpf_struct_ops_link_create() removing/adding.
      
       - Rename REGISTER_BPF_STRUCT_OPS() to register_bpf_struct_ops().
      
       - Implement bpf_map_struct_ops_info_fill() for !CONFIG_BPF_JIT.
      
      Changes from v15:
      
       - Fix the misleading commit message of part 4.
      
       - Introduce BPF_F_VTYPE_BTF_OBJ_FD flag to struct bpf_attr to tell
         if value_type_btf_obj_fd is set or not.
      
       - Introduce links_cnt to struct bpf_struct_ops_map to avoid accessing
         struct bpf_struct_ops_desc in bpf_struct_ops_map_put_progs() after
         calling module_put() against the owner module of the struct_ops
         type. (Part 9)
      
      Changes from v14:
      
       - Rebase. Add cif_stub required by
         the commit 2cd3e377 ("x86/cfi,bpf: Fix bpf_struct_ops CFI")
      
       - Remove creating struct_ops map without bpf_testmod.ko from the
         test.
      
       - Check the name of btf returned by bpf_map_info by getting the name
         with bpf_btf_get_info_by_fd().
      
       - Change value_type_btf_obj_fd to a signed type to allow the 0 fd.
      
      Changes from v13:
      
       - Change the test case to use bpf_map_create() to create a struct_ops
         map while testmod.ko is unloaded.
      
       - Move bpf_struct_ops_find*() to btf.c.
      
       - Use btf_is_module() to replace btf != btf_vmlinux.
      
      Changes from v12:
      
       - Rebase to for-next to fix conflictions.
      
      Changes from v11:
      
       - bpf_struct_ops_maps hold only the refcnt to the module, but not
         btf. (patch 1)
      
       - Fix warning messages. (patch 1, 9 and 10)
      
       - Remove unnecessary conditional compiling of CONFIG_BPF_JIT.
         (patch 4, 9 and 10)
      
       - Fix the commit log of the patch 7 to explain how a btf is pass from
         the user space and how the kernel handle it.
      
       - bpf_struct_ops_maps hold the module defining it's type, but not
         btf. A map will hold the module through its life-span from
         allocating to being free. (patch 8)
      
       - Change selftests and tracing __bpf_struct_ops_map_free() to wait
         for the release of the bpf_testmod module.
      
       - Include btf_obj_id in bpf_map_info. (patch 14)
      
      Changes from v10:
      
       - Guard btf.c from CONFIG_BPF_JIT=n. This patchset has introduced
         symbols from bpf_struct_ops.c which is only built when
         CONFIG_BPF_JIT=y.
      
       - Fix the warning of unused errout_free label by moving code that is
         leaked to patch 8 to patch 7.
      
      Changes from v9:
      
       - Remove the call_rcu_tasks_trace() changes from kern_sync_rcu().
      
       - Trace btf_put() in the test case to ensure the release of kmod's
         btf, or the consequent tests may fail for using kmod's unloaded old
         btf instead the new one created after loading again. The kmod's btf
         may live for awhile after unloading the kmod, for a map being freed
         asynchronized is still holding the btf.
      
       - Split "add struct_ops_tab to btf" into tow patches by adding
         "make struct_ops_map support btfs other than btf_vmlinux".
      
       - Flip the order of "pass attached BTF to the bpf_struct_ops
         subsystem" and "hold module for bpf_struct_ops_map" to make it more
         reasonable.
      
       - Fix the compile errors of a missing header file.
      
      Changes from v8:
      
       - Rename bpf_struct_ops_init_one() to bpf_struct_ops_desc_init().
      
       - Move code that using BTF_ID_LIST to the newly added patch 2.
      
       - Move code that lookup struct_ops types from a given module to the
         newly added patch 5.
      
       - Store the pointers of btf at st_maps.
      
       - Add test cases for the cases of modules being unload.
      
       - Call bpf_struct_ops_init() in btf_add_struct_ops() to fix an
         inconsistent issue.
      
      Changes from v7:
      
       - Fix check_struct_ops_btf_id() to use attach btf if there is instead
         of btf_vmlinux.
      
      Changes from v6:
      
       - Change returned error code to -EINVAL for the case of
         bpf_try_get_module().
      
       - Return an error code from bpf_struct_ops_init().
      
       - Fix the dependency issue of testing_helpers.c and
         rcu_tasks_trace_gp.skel.h.
      
      Changes from v5:
      
       - As the 2nd patch, we introduce "bpf_struct_ops_desc". This change
         involves moving certain members of "bpf_struct_ops" to
         "bpf_struct_ops_desc", which becomes a part of
         "btf_struct_ops_tab". This ensures that these members remain
         accessible even when the owner module of a "bpf_struct_ops" is
         unloaded.
      
       - Correct the order of arguments when calling
          in the 3rd patch.
      
       - Remove the owner argument from bpf_struct_ops_init_one(). Instead,
         callers should fill in st_ops->owner.
      
       - Make sure to hold the owner module when calling
         bpf_struct_ops_find() and bpf_struct_ops_find_value() in the 6th
         patch.
      
       - Merge the functions register_bpf_struct_ops_btf() and
         register_bpf_struct_ops() into a single function and relocate it to
         btf.c for better organization and clarity.
      
       - Undo the name modifications made to find_kernel_btf_id() and
         find_ksym_btf_id() in the 8th patch.
      
      Changes from v4:
      
       - Fix the dependency between testing_helpers.o and
         rcu_tasks_trace_gp.skel.h.
      
      Changes from v3:
      
       - Fix according to the feedback for v3.
      
         - Change of the order of arguments to make btf as the first
           argument.
      
         - Use btf_try_get_module() instead of try_get_module() since the
           module pointed by st_ops->owner can gone while some one is still
           holding its btf.
      
         - Move variables defined by BPF_STRUCT_OPS_COMMON_VALUE to struct
           bpf_struct_ops_common_value to validation easier.
      
         - Register the struct_ops type defined by bpf_testmod in its init
           function.
      
         - Rename field name to 'value_type_btf_obj_fd' to make it explicit.
      
         - Fix leaking of btf objects on error.
      
         - st_maps hold their modules to keep modules alive and prevent they
           from unloading.
      
         - bpf_map of libbpf keeps mod_btf_fd instead of a pointer to module_btf.
      
         - Do call_rcu_tasks_trace() in kern_sync_rcu() to ensure the
           bpf_testmod is unloaded properly. It uses rcu_tasks_trace_gp to
           trigger call_rcu_tasks_trace() in the kernel.
      
       - Merge and reorder patches in a reasonable order.
      
      Changes from v2:
      
       - Remove struct_ops array, and add a per-btf (module) struct_ops_tab
         to collect registered struct_ops types.
      
       - Validate value_type by checking member names and types.
      ---
      v16: https://lore.kernel.org/all/20240118014930.1992551-1-thinker.li@gmail.com/
      v15: https://lore.kernel.org/all/20231220222654.1435895-1-thinker.li@gmail.com/
      v14: https://lore.kernel.org/all/20231217081132.1025020-1-thinker.li@gmail.com/
      v13: https://lore.kernel.org/all/20231209002709.535966-1-thinker.li@gmail.com/
      v12: https://lore.kernel.org/all/20231207013950.1689269-1-thinker.li@gmail.com/
      v11: https://lore.kernel.org/all/20231106201252.1568931-1-thinker.li@gmail.com/
      v10: https://lore.kernel.org/all/20231103232202.3664407-1-thinker.li@gmail.com/
      v9: https://lore.kernel.org/all/20231101204519.677870-1-thinker.li@gmail.com/
      v8: https://lore.kernel.org/all/20231030192810.382942-1-thinker.li@gmail.com/
      v7: https://lore.kernel.org/all/20231027211702.1374597-1-thinker.li@gmail.com/
      v6: https://lore.kernel.org/all/20231022050335.2579051-11-thinker.li@gmail.com/
      v5: https://lore.kernel.org/all/20231017162306.176586-1-thinker.li@gmail.com/
      v4: https://lore.kernel.org/all/20231013224304.187218-1-thinker.li@gmail.com/
      v3: https://lore.kernel.org/all/20230920155923.151136-1-thinker.li@gmail.com/
      v2: https://lore.kernel.org/all/20230913061449.1918219-1-thinker.li@gmail.com/
      
      
      ====================
      
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      8b593021
    • Kui-Feng Lee's avatar
      selftests/bpf: test case for register_bpf_struct_ops(). · 0253e059
      Kui-Feng Lee authored
      
      
      Create a new struct_ops type called bpf_testmod_ops within the bpf_testmod
      module. When a struct_ops object is registered, the bpf_testmod module will
      invoke test_2 from the module.
      
      Signed-off-by: default avatarKui-Feng Lee <thinker.li@gmail.com>
      Link: https://lore.kernel.org/r/20240119225005.668602-15-thinker.li@gmail.com
      
      
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      0253e059