1. 20 Dec, 2023 21 commits
    • Alexei Starovoitov's avatar
      Merge branch 'bpf-fix-warning-in-check_obj_size' · 92999245
      Alexei Starovoitov authored
      Hou Tao says:
      
      ====================
      bpf: Fix warning in check_obj_size()
      
      From: Hou Tao <houtao1@huawei.com>
      
      Hi,
      
      The patch set aims to fix the warning in check_obj_size() as reported by
      lkp [1]. Patch #1 fixes the warning by selecting target cache for free
      request through c->unit_size, so the unnecessary adjustment of
      size_index and the checking in check_obj_size() can be removed. Patch #2
      fixes the test failure in test_bpf_ma after applying patch #1.
      
      Please see individual patches for more details. And comments are always
      welcome.
      
      [1]: https://lore.kernel.org/bpf/202310302113.9f8fe705-oliver.sang@intel.com/
      ====================
      
      Link: https://lore.kernel.org/r/20231216131052.27621-1-houtao@huaweicloud.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      92999245
    • Hou Tao's avatar
      selftests/bpf: Remove tests for zeroed-array kptr · 69ff403d
      Hou Tao authored
      bpf_mem_alloc() doesn't support zero-sized allocation, so removing these
      tests from test_bpf_ma test. After the removal, there will no definition
      for bin_data_8, so remove 8 from data_sizes array and adjust the index
      of data_btf_ids array in all test cases accordingly.
      Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
      Link: https://lore.kernel.org/r/20231216131052.27621-3-houtao@huaweicloud.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      69ff403d
    • Hou Tao's avatar
      bpf: Use c->unit_size to select target cache during free · 7ac5c53e
      Hou Tao authored
      At present, bpf memory allocator uses check_obj_size() to ensure that
      ksize() of allocated pointer is equal with the unit_size of used
      bpf_mem_cache. Its purpose is to prevent bpf_mem_free() from selecting
      a bpf_mem_cache which has different unit_size compared with the
      bpf_mem_cache used for allocation. But as reported by lkp, the return
      value of ksize() or kmalloc_size_roundup() may change due to slab merge
      and it will lead to the warning report in check_obj_size().
      
      The reported warning happened as follows:
      (1) in bpf_mem_cache_adjust_size(), kmalloc_size_roundup(96) returns the
      object_size of kmalloc-96 instead of kmalloc-cg-96. The object_size of
      kmalloc-96 is 96, so size_index for 96 is not adjusted accordingly.
      (2) the object_size of kmalloc-cg-96 is adjust from 96 to 128 due to
      slab merge in __kmem_cache_alias(). For SLAB, SLAB_HWCACHE_ALIGN is
      enabled by default for kmalloc slab, so align is 64 and size is 128 for
      kmalloc-cg-96. SLUB has a similar merge logic, but its object_size will
      not be changed, because its align is 8 under x86-64.
      (3) when unit_alloc() does kmalloc_node(96, __GFP_ACCOUNT, node),
      ksize() returns 128 instead of 96 for the returned pointer.
      (4) the warning in check_obj_size() is triggered.
      
      Considering the slab merge can happen in anytime (e.g, a slab created in
      a new module), the following case is also possible: during the
      initialization of bpf_global_ma, there is no slab merge and ksize() for
      a 96-bytes object returns 96. But after that a new slab created by a
      kernel module is merged to kmalloc-cg-96 and the object_size of
      kmalloc-cg-96 is adjust from 96 to 128 (which is possible for x86-64 +
      CONFIG_SLAB, because its alignment requirement is 64 for 96-bytes slab).
      So soon or later, when bpf_global_ma frees a 96-byte-sized pointer
      which is allocated from bpf_mem_cache with unit_size=96, bpf_mem_free()
      will free the pointer through a bpf_mem_cache in which unit_size is 128,
      because the return value of ksize() changes. The warning for the
      mismatch will be triggered again.
      
      A feasible fix is introducing similar APIs compared with ksize() and
      kmalloc_size_roundup() to return the actually-allocated size instead of
      size which may change due to slab merge, but it will introduce
      unnecessary dependency on the implementation details of mm subsystem.
      
      As for now the pointer of bpf_mem_cache is saved in the 8-bytes area
      (or 4-bytes under 32-bit host) above the returned pointer, using
      unit_size in the saved bpf_mem_cache to select the target cache instead
      of inferring the size from the pointer itself. Beside no extra
      dependency on mm subsystem, the performance for bpf_mem_free_rcu() is
      also improved as shown below.
      
      Before applying the patch, the performances of bpf_mem_alloc() and
      bpf_mem_free_rcu() on 8-CPUs VM with one producer are as follows:
      
      kmalloc : alloc 11.69 ± 0.28M/s free 29.58 ± 0.93M/s
      percpu  : alloc 14.11 ± 0.52M/s free 14.29 ± 0.99M/s
      
      After apply the patch, the performance for bpf_mem_free_rcu() increases
      9% and 146% for kmalloc memory and per-cpu memory respectively:
      
      kmalloc: alloc 11.01 ± 0.03M/s free   32.42 ± 0.48M/s
      percpu:  alloc 12.84 ± 0.12M/s free   35.24 ± 0.23M/s
      
      After the fixes, there is no need to adjust size_index to fix the
      mismatch between allocation and free, so remove it as well. Also return
      NULL instead of ZERO_SIZE_PTR for zero-sized alloc in bpf_mem_alloc(),
      because there is no bpf_mem_cache pointer saved above ZERO_SIZE_PTR.
      
      Fixes: 9077fc22 ("bpf: Use kmalloc_size_roundup() to adjust size_index")
      Reported-by: default avatarkernel test robot <oliver.sang@intel.com>
      Closes: https://lore.kernel.org/bpf/202310302113.9f8fe705-oliver.sang@intel.comSigned-off-by: default avatarHou Tao <houtao1@huawei.com>
      Link: https://lore.kernel.org/r/20231216131052.27621-2-houtao@huaweicloud.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      7ac5c53e
    • Colin Ian King's avatar
      samples/bpf: Use %lu format specifier for unsigned long values · 32f24938
      Colin Ian King authored
      Currently %ld format specifiers are being used for unsigned long
      values. Fix this by using %lu instead. Cleans up cppcheck warnings:
      
      warning: %ld in format string (no. 1) requires 'long' but the argument
      type is 'unsigned long'. [invalidPrintfArgType_sint]
      Signed-off-by: default avatarColin Ian King <colin.i.king@gmail.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Reviewed-by: default avatarRandy Dunlap <rdunlap@infradead.org>
      Link: https://lore.kernel.org/bpf/20231219152307.368921-1-colin.i.king@gmail.com
      32f24938
    • Hou Tao's avatar
      selftests/bpf: Close cgrp fd before calling cleanup_cgroup_environment() · 441c725e
      Hou Tao authored
      There is error log when htab-mem benchmark completes. The error log
      looks as follows:
      
      $ ./bench htab-mem -d1
      Setting up benchmark 'htab-mem'...
      Benchmark 'htab-mem' started.
      ......
      (cgroup_helpers.c:353: errno: Device or resource busy) umount cgroup2
      
      Fix it by closing cgrp fd before invoking cleanup_cgroup_environment().
      Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
      Link: https://lore.kernel.org/r/20231219135727.2661527-1-houtao@huaweicloud.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      441c725e
    • Alexei Starovoitov's avatar
      Merge branch 'enhance-bpf-global-subprogs-with-argument-tags' · 85dd93ac
      Alexei Starovoitov authored
      Andrii Nakryiko says:
      
      ====================
      Enhance BPF global subprogs with argument tags
      
      This patch set adds verifier support for annotating user's global BPF subprog
      arguments with few commonly requested annotations, to improve global subprog
      verification experience.
      
      These tags are:
        - ability to annotate a special PTR_TO_CTX argument;
        - ability to annotate a generic PTR_TO_MEM as non-null.
      
      We utilize btf_decl_tag attribute for this and provide two helper macros as
      part of bpf_helpers.h in libbpf (patch #8).
      
      Besides this we also add abilit to pass a pointer to dynptr into global
      subprog. This is done based on type name match (struct bpf_dynptr *). This
      allows to pass dynptrs into global subprogs, for use cases that deal with
      variable-sized generic memory pointers.
      
      Big chunk of the patch set (patches #1 through #5) are various refactorings to
      make verifier internals around global subprog validation logic easier to
      extend and support long term, eliminating BTF parsing logic duplication,
      factoring out argument expectation definitions from BTF parsing, etc.
      
      New functionality is added in patch #6 (ctx and non-null) and patch #7
      (dynptr), extending global subprog checks with awareness for arg tags.
      
      Patch #9 adds simple tests validating each of the added tags and dynptr
      argument passing.
      
      Patch #10 adds a simple negative case for freplace programs to make sure that
      target BPF programs with "unreliable" BTF func proto cannot be freplaced.
      
      v2->v3:
        - patch #10 improved by checking expected verifier error (Eduard);
      v1->v2:
        - dropped packet args for now (Eduard);
        - added back unreliable=true detection for entry BPF programs (Eduard);
        - improved subprog arg validation (Eduard);
        - switched dynptr arg from tag to just type name based check (Eduard).
      ====================
      
      Link: https://lore.kernel.org/r/20231215011334.2307144-1-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      85dd93ac
    • Andrii Nakryiko's avatar
      selftests/bpf: add freplace of BTF-unreliable main prog test · f0a50562
      Andrii Nakryiko authored
      Add a test validating that freplace'ing another main (entry) BPF program
      fails if the target BPF program doesn't have valid/expected func proto BTF.
      
      We extend fexit_bpf2bpf test to allow to specify expected log message
      for negative test cases (where freplace program is expected to fail to
      load).
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-11-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      f0a50562
    • Andrii Nakryiko's avatar
      selftests/bpf: add global subprog annotation tests · 0a0ffcac
      Andrii Nakryiko authored
      Add test cases to validate semantics of global subprog argument
      annotations:
        - non-null pointers;
        - context argument;
        - const dynptr passing;
        - packet pointers (data, metadata, end).
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-10-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      0a0ffcac
    • Andrii Nakryiko's avatar
      libbpf: add __arg_xxx macros for annotating global func args · aae9c25d
      Andrii Nakryiko authored
      Add a set of __arg_xxx macros which can be used to augment BPF global
      subprogs/functions with extra information for use by BPF verifier.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-9-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      aae9c25d
    • Andrii Nakryiko's avatar
      bpf: add support for passing dynptr pointer to global subprog · a64bfe61
      Andrii Nakryiko authored
      Add ability to pass a pointer to dynptr into global functions.
      This allows to have global subprogs that accept and work with generic
      dynptrs that are created by caller. Dynptr argument is detected based on
      the name of a struct type, if it's "bpf_dynptr", it's assumed to be
      a proper dynptr pointer. Both actual struct and forward struct
      declaration types are supported.
      
      This is conceptually exactly the same semantics as
      bpf_user_ringbuf_drain()'s use of dynptr to pass a variable-sized
      pointer to ringbuf record. So we heavily rely on CONST_PTR_TO_DYNPTR
      bits of already existing logic in the verifier.
      
      During global subprog validation, we mark such CONST_PTR_TO_DYNPTR as
      having LOCAL type, as that's the most unassuming type of dynptr and it
      doesn't have any special helpers that can try to free or acquire extra
      references (unlike skb, xdp, or ringbuf dynptr). So that seems like a safe
      "choice" to make from correctness standpoint. It's still possible to
      pass any type of dynptr to such subprog, though, because generic dynptr
      helpers, like getting data/slice pointers, read/write memory copying
      routines, dynptr adjustment and getter routines all work correctly with
      any type of dynptr.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-8-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      a64bfe61
    • Andrii Nakryiko's avatar
      bpf: support 'arg:xxx' btf_decl_tag-based hints for global subprog args · 94e1c70a
      Andrii Nakryiko authored
      Add support for annotating global BPF subprog arguments to provide more
      information about expected semantics of the argument. Currently,
      verifier relies purely on argument's BTF type information, and supports
      three general use cases: scalar, pointer-to-context, and
      pointer-to-fixed-size-memory.
      
      Scalar and pointer-to-fixed-mem work well in practice and are quite
      natural to use. But pointer-to-context is a bit problematic, as typical
      BPF users don't realize that they need to use a special type name to
      signal to verifier that argument is not just some pointer, but actually
      a PTR_TO_CTX. Further, even if users do know which type to use, it is
      limiting in situations where the same BPF program logic is used across
      few different program types. Common case is kprobes, tracepoints, and
      perf_event programs having a helper to send some data over BPF perf
      buffer. bpf_perf_event_output() requires `ctx` argument, and so it's
      quite cumbersome to share such global subprog across few BPF programs of
      different types, necessitating extra static subprog that is context
      type-agnostic.
      
      Long story short, there is a need to go beyond types and allow users to
      add hints to global subprog arguments to define expectations.
      
      This patch adds such support for two initial special tags:
        - pointer to context;
        - non-null qualifier for generic pointer arguments.
      
      All of the above came up in practice already and seem generally useful
      additions. Non-null qualifier is an often requested feature, which
      currently has to be worked around by having unnecessary NULL checks
      inside subprogs even if we know that arguments are never NULL. Pointer
      to context was discussed earlier.
      
      As for implementation, we utilize btf_decl_tag attribute and set up an
      "arg:xxx" convention to specify argument hint. As such:
        - btf_decl_tag("arg:ctx") is a PTR_TO_CTX hint;
        - btf_decl_tag("arg:nonnull") marks pointer argument as not allowed to
          be NULL, making NULL check inside global subprog unnecessary.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-7-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      94e1c70a
    • Andrii Nakryiko's avatar
      bpf: reuse subprog argument parsing logic for subprog call checks · f18c3d88
      Andrii Nakryiko authored
      Remove duplicated BTF parsing logic when it comes to subprog call check.
      Instead, use (potentially cached) results of btf_prepare_func_args() to
      abstract away expectations of each subprog argument in generic terms
      (e.g., "this is pointer to context", or "this is a pointer to memory of
      size X"), and then use those simple high-level argument type
      expectations to validate actual register states to check if they match
      expectations.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-6-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      f18c3d88
    • Andrii Nakryiko's avatar
      bpf: move subprog call logic back to verifier.c · c5a72447
      Andrii Nakryiko authored
      Subprog call logic in btf_check_subprog_call() currently has both a lot
      of BTF parsing logic (which is, presumably, what justified putting it
      into btf.c), but also a bunch of register state checks, some of each
      utilize deep verifier logic helpers, necessarily exported from
      verifier.c: check_ptr_off_reg(), check_func_arg_reg_off(),
      and check_mem_reg().
      
      Going forward, btf_check_subprog_call() will have a minimum of
      BTF-related logic, but will get more internal verifier logic related to
      register state manipulation. So move it into verifier.c to minimize
      amount of verifier-specific logic exposed to btf.c.
      
      We do this move before refactoring btf_check_func_arg_match() to
      preserve as much history post-refactoring as possible.
      
      No functional changes.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-5-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c5a72447
    • Andrii Nakryiko's avatar
      bpf: prepare btf_prepare_func_args() for handling static subprogs · e26080d0
      Andrii Nakryiko authored
      Generalize btf_prepare_func_args() to support both global and static
      subprogs. We are going to utilize this property in the next patch,
      reusing btf_prepare_func_args() for subprog call logic instead of
      reparsing BTF information in a completely separate implementation.
      
      btf_prepare_func_args() now detects whether subprog is global or static
      makes slight logic adjustments for static func cases, like not failing
      fatally (-EFAULT) for conditions that are allowable for static subprogs.
      
      Somewhat subtle (but major!) difference is the handling of pointer arguments.
      Both global and static functions need to handle special context
      arguments (which are pointers to predefined type names), but static
      subprogs give up on any other pointers, falling back to marking subprog
      as "unreliable", disabling the use of BTF type information altogether.
      
      For global functions, though, we are assuming that such pointers to
      unrecognized types are just pointers to fixed-sized memory region (or
      error out if size cannot be established, like for `void *` pointers).
      
      This patch accommodates these small differences and sets up a stage for
      refactoring in the next patch, eliminating a separate BTF-based parsing
      logic in btf_check_func_arg_match().
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-4-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      e26080d0
    • Andrii Nakryiko's avatar
      bpf: reuse btf_prepare_func_args() check for main program BTF validation · 5eccd2db
      Andrii Nakryiko authored
      Instead of btf_check_subprog_arg_match(), use btf_prepare_func_args()
      logic to validate "trustworthiness" of main BPF program's BTF information,
      if it is present.
      
      We ignored results of original BTF check anyway, often times producing
      confusing and ominously-sounding "reg type unsupported for arg#0
      function" message, which has no apparent effect on program correctness
      and verification process.
      
      All the -EFAULT returning sanity checks are already performed in
      check_btf_info_early(), so there is zero reason to have this duplication
      of logic between btf_check_subprog_call() and btf_check_subprog_arg_match().
      Dropping btf_check_subprog_arg_match() simplifies
      btf_check_func_arg_match() further removing `bool processing_call` flag.
      
      One subtle bit that was done by btf_check_subprog_arg_match() was
      potentially marking main program's BTF as unreliable. We do this
      explicitly now with a dedicated simple check, preserving the original
      behavior, but now based on well factored btf_prepare_func_args() logic.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-3-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      5eccd2db
    • Andrii Nakryiko's avatar
      bpf: abstract away global subprog arg preparation logic from reg state setup · 4ba1d0f2
      Andrii Nakryiko authored
      btf_prepare_func_args() is used to understand expectations and
      restrictions on global subprog arguments. But current implementation is
      hard to extend, as it intermixes BTF-based func prototype parsing and
      interpretation logic with setting up register state at subprog entry.
      
      Worse still, those registers are not completely set up inside
      btf_prepare_func_args(), requiring some more logic later in
      do_check_common(). Like calling mark_reg_unknown() and similar
      initialization operations.
      
      This intermixing of BTF interpretation and register state setup is
      problematic. First, it causes duplication of BTF parsing logic for global
      subprog verification (to set up initial state of global subprog) and
      global subprog call sites analysis (when we need to check that whatever
      is being passed into global subprog matches expectations), performed in
      btf_check_subprog_call().
      
      Given we want to extend global func argument with tags later, this
      duplication is problematic. So refactor btf_prepare_func_args() to do
      only BTF-based func proto and args parsing, returning high-level
      argument "expectations" only, with no regard to specifics of register
      state. I.e., if it's a context argument, instead of setting register
      state to PTR_TO_CTX, we return ARG_PTR_TO_CTX enum for that argument as
      "an argument specification" for further processing inside
      do_check_common(). Similarly for SCALAR arguments, PTR_TO_MEM, etc.
      
      This allows to reuse btf_prepare_func_args() in following patches at
      global subprog call site analysis time. It also keeps register setup
      code consistently in one place, do_check_common().
      
      Besides all this, we cache this argument specs information inside
      env->subprog_info, eliminating the need to redo these potentially
      expensive BTF traversals, especially if BPF program's BTF is big and/or
      there are lots of global subprog calls.
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231215011334.2307144-2-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      4ba1d0f2
    • Alexei Starovoitov's avatar
      Merge branch 'bpf-support-to-track-bpf_jne' · c337f237
      Alexei Starovoitov authored
      Menglong Dong says:
      
      ====================
      bpf: support to track BPF_JNE
      
      For now, the reg bounds is not handled for BPF_JNE case, which can cause
      the failure of following case:
      
        /* The type of "a" is u32 */
        if (a > 0 && a < 100) {
          /* the range of the register for a is [0, 99], not [1, 99],
           * and will cause the following error:
           *
           *   invalid zero-sized read
           *
           * as a can be 0.
           */
          bpf_skb_store_bytes(skb, xx, xx, a, 0);
        }
      
      In the code above, "a > 0" will be compiled to "if a == 0 goto xxx". In
      the TRUE branch, the dst_reg will be marked as known to 0. However, in the
      fallthrough(FALSE) branch, the dst_reg will not be handled, which makes
      the [min, max] for a is [0, 99], not [1, 99].
      
      In the 1st patch, we reduce the range of the dst reg if the src reg is a
      const and is exactly the edge of the dst reg For BPF_JNE.
      
      In the 2nd patch, we remove reduplicated s32 casting in "crafted_cases".
      
      In the 3rd patch, we just activate the test case for this logic in
      range_cond(), which is committed by Andrii in the
      commit 88632389 ("selftests/bpf: BPF register range bounds tester").
      
      In the 4th patch, we convert the case above to a testcase and add it to
      verifier_bounds.c.
      
      Changes since v4:
      - add the 2nd patch
      - add "{U32, U32, {0, U32_MAX}, {U32_MAX, U32_MAX}}" that we missed in the
        3rd patch
      - add some comments to the function that we add in the 4th patch
      - add reg_not_equal_const() in the 4th patch
      
      Changes since v3:
      - do some adjustment to the crafted cases that we added in the 2nd patch
      - add the 3rd patch
      
      Changes since v2:
      - fix a typo in the subject of the 1st patch
      - add some comments to the 1st patch, as Eduard advised
      - add some cases to the "crafted_cases"
      
      Changes since v1:
      - simplify the code in the 1st patch
      - introduce the 2nd patch for the testing
      ====================
      
      Link: https://lore.kernel.org/r/20231219134800.1550388-1-menglong8.dong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c337f237
    • Menglong Dong's avatar
      selftests/bpf: add testcase to verifier_bounds.c for BPF_JNE · 463ea64e
      Menglong Dong authored
      Add testcase for the logic that the verifier tracks the BPF_JNE for regs.
      The assembly function "reg_not_equal_const()" and "reg_equal_const" that
      we add is exactly converted from the following case:
      
        u32 a = bpf_get_prandom_u32();
        u64 b = 0;
      
        a %= 8;
        /* the "a > 0" here will be optimized to "a != 0" */
        if (a > 0) {
          /* now the range of a should be [1, 7] */
          bpf_skb_store_bytes(skb, 0, &b, a, 0);
        }
      Signed-off-by: default avatarMenglong Dong <menglong8.dong@gmail.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231219134800.1550388-5-menglong8.dong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      463ea64e
    • Menglong Dong's avatar
      selftests/bpf: activate the OP_NE logic in range_cond() · 31d9cc96
      Menglong Dong authored
      The edge range checking for the registers is supported by the verifier
      now, so we can activate the extended logic in
      tools/testing/selftests/bpf/prog_tests/reg_bounds.c/range_cond() to test
      such logic.
      
      Besides, I added some cases to the "crafted_cases" array for this logic.
      These cases are mainly used to test the edge of the src reg and dst reg.
      
      All reg bounds testings has passed in the SLOW_TESTS mode:
      
      $ export SLOW_TESTS=1 && ./test_progs -t reg_bounds -j
      Summary: 65/18959832 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: default avatarMenglong Dong <menglong8.dong@gmail.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231219134800.1550388-4-menglong8.dong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      31d9cc96
    • Menglong Dong's avatar
      selftests/bpf: remove reduplicated s32 casting in "crafted_cases" · 1de58483
      Menglong Dong authored
      The "S32_MIN" is already defined with s32 casting, so there is no need
      to do it again.
      Signed-off-by: default avatarMenglong Dong <menglong8.dong@gmail.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20231219134800.1550388-3-menglong8.dong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      1de58483
    • Menglong Dong's avatar
      bpf: make the verifier tracks the "not equal" for regs · d028f875
      Menglong Dong authored
      We can derive some new information for BPF_JNE in regs_refine_cond_op().
      Take following code for example:
      
        /* The type of "a" is u32 */
        if (a > 0 && a < 100) {
          /* the range of the register for a is [0, 99], not [1, 99],
           * and will cause the following error:
           *
           *   invalid zero-sized read
           *
           * as a can be 0.
           */
          bpf_skb_store_bytes(skb, xx, xx, a, 0);
        }
      
      In the code above, "a > 0" will be compiled to "jmp xxx if a == 0". In the
      TRUE branch, the dst_reg will be marked as known to 0. However, in the
      fallthrough(FALSE) branch, the dst_reg will not be handled, which makes
      the [min, max] for a is [0, 99], not [1, 99].
      
      For BPF_JNE, we can reduce the range of the dst reg if the src reg is a
      const and is exactly the edge of the dst reg.
      Signed-off-by: default avatarMenglong Dong <menglong8.dong@gmail.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarShung-Hsi Yu <shung-hsi.yu@suse.com>
      Link: https://lore.kernel.org/r/20231219134800.1550388-2-menglong8.dong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      d028f875
  2. 19 Dec, 2023 19 commits