1. 14 Jul, 2023 35 commits
  2. 13 Jul, 2023 5 commits
    • Yafang Shao's avatar
      selftests/bpf: Add selftest for PTR_UNTRUSTED · 1cd0e771
      Yafang Shao authored
      Add a new selftest to check the PTR_UNTRUSTED condition. Below is the
      result,
      
       #160     ptr_untrusted:OK
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Link: https://lore.kernel.org/r/20230713025642.27477-5-laoar.shao@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      1cd0e771
    • Yafang Shao's avatar
      bpf: Fix an error in verifying a field in a union · 33937607
      Yafang Shao authored
      We are utilizing BPF LSM to monitor BPF operations within our container
      environment. When we add support for raw_tracepoint, it hits below
      error.
      
      ; (const void *)attr->raw_tracepoint.name);
      27: (79) r3 = *(u64 *)(r2 +0)
      access beyond the end of member map_type (mend:4) in struct (anon) with off 0 size 8
      
      It can be reproduced with below BPF prog.
      
      SEC("lsm/bpf")
      int BPF_PROG(bpf_audit, int cmd, union bpf_attr *attr, unsigned int size)
      {
      	switch (cmd) {
      	case BPF_RAW_TRACEPOINT_OPEN:
      		bpf_printk("raw_tracepoint is %s", attr->raw_tracepoint.name);
      		break;
      	default:
      		break;
      	}
      	return 0;
      }
      
      The reason is that when accessing a field in a union, such as bpf_attr,
      if the field is located within a nested struct that is not the first
      member of the union, it can result in incorrect field verification.
      
        union bpf_attr {
            struct {
                __u32 map_type; <<<< Actually it will find that field.
                __u32 key_size;
                __u32 value_size;
               ...
            };
            ...
            struct {
                __u64 name;    <<<< We want to verify this field.
                __u32 prog_fd;
            } raw_tracepoint;
        };
      
      Considering the potential deep nesting levels, finding a perfect
      solution to address this issue has proven challenging. Therefore, I
      propose a solution where we simply skip the verification process if the
      field in question is located within a union.
      
      Fixes: 7e3617a7 ("bpf: Add array support to btf_struct_access")
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Link: https://lore.kernel.org/r/20230713025642.27477-4-laoar.shao@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      33937607
    • Yafang Shao's avatar
      selftests/bpf: Add selftests for nested_trust · d2284d68
      Yafang Shao authored
      Add selftests for nested_strust to check whehter PTR_UNTRUSTED is cleared
      as expected, the result as follows:
      
       #141/1   nested_trust/test_read_cpumask:OK
       #141/2   nested_trust/test_skb_field:OK                    <<<<
       #141/3   nested_trust/test_invalid_nested_user_cpus:OK
       #141/4   nested_trust/test_invalid_nested_offset:OK
       #141/5   nested_trust/test_invalid_skb_field:OK            <<<<
       #141     nested_trust:OK
      
      The #141/2 and #141/5 are newly added.
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Link: https://lore.kernel.org/r/20230713025642.27477-3-laoar.shao@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      d2284d68
    • Yafang Shao's avatar
      bpf: Fix an error around PTR_UNTRUSTED · 7ce4dc3e
      Yafang Shao authored
      Per discussion with Alexei, the PTR_UNTRUSTED flag should not been
      cleared when we start to walk a new struct, because the struct in
      question may be a struct nested in a union. We should also check and set
      this flag before we walk its each member, in case itself is a union.
      We will clear this flag if the field is BTF_TYPE_SAFE_RCU_OR_NULL.
      
      Fixes: 6fcd486b ("bpf: Refactor RCU enforcement in the verifier.")
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Link: https://lore.kernel.org/r/20230713025642.27477-2-laoar.shao@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      7ce4dc3e
    • Alexei Starovoitov's avatar
      Merge branch 'bpf-x86-allow-function-arguments-up-to-12-for-tracing' · f892cac2
      Alexei Starovoitov authored
      Menglong Dong says:
      
      ====================
      bpf, x86: allow function arguments up to 12 for TRACING
      
      From: Menglong Dong <imagedong@tencent.com>
      
      For now, the BPF program of type BPF_PROG_TYPE_TRACING can only be used
      on the kernel functions whose arguments count less than or equal to 6, if
      not considering '> 8 bytes' struct argument. This is not friendly at all,
      as too many functions have arguments count more than 6. According to the
      current kernel version, below is a statistics of the function arguments
      count:
      
      argument count | function count
      7              | 704
      8              | 270
      9              | 84
      10             | 47
      11             | 47
      12             | 27
      13             | 22
      14             | 5
      15             | 0
      16             | 1
      
      Therefore, let's enhance it by increasing the function arguments count
      allowed in arch_prepare_bpf_trampoline(), for now, only x86_64.
      
      In the 1st patch, we save/restore regs with BPF_DW size to make the code
      in save_regs()/restore_regs() simpler.
      
      In the 2nd patch, we make arch_prepare_bpf_trampoline() support to copy
      function arguments in stack for x86 arch. Therefore, the maximum
      arguments can be up to MAX_BPF_FUNC_ARGS for FENTRY, FEXIT and
      MODIFY_RETURN. Meanwhile, we clean the potential garbage value when we
      copy the arguments on-stack.
      
      And the 3rd patch is for the testcases of the this series.
      
      Changes since v9:
      - fix the failed test cases of trampoline_count and get_func_args_test
        in the 3rd patch
      
      Changes since v8:
      - change the way to test fmod_ret in the 3rd patch
      
      Changes since v7:
      - split the testcases, and add fentry_many_args/fexit_many_args to
        DENYLIST.aarch64 in 3rd patch
      
      Changes since v6:
      - somit nits from commit message and comment in the 1st patch
      - remove the inline in get_nr_regs() in the 1st patch
      - rename some function and various in the 1st patch
      
      Changes since v5:
      - adjust the commit log of the 1st patch, avoiding confusing people that
        bugs exist in current code
      - introduce get_nr_regs() to get the space that used to pass args on
        stack correct in the 2nd patch
      - add testcases to tracing_struct.c instead of fentry_test.c and
        fexit_test.c
      
      Changes since v4:
      - consider the case of the struct in arguments can't be hold by regs
      - add comment for some code
      - add testcases for MODIFY_RETURN
      - rebase to the latest
      
      Changes since v3:
      - try make the stack pointer 16-byte aligned. Not sure if I'm right :)
      - introduce clean_garbage() to clean the grabage when argument count is 7
      - use different data type in bpf_testmod_fentry_test{7,12}
      - add testcase for grabage values in ctx
      
      Changes since v2:
      - keep MAX_BPF_FUNC_ARGS still
      - clean garbage value in upper bytes in the 2nd patch
      - move bpf_fentry_test{7,12} to bpf_testmod.c and rename them to
        bpf_testmod_fentry_test{7,12} meanwhile in the 3rd patch
      
      Changes since v1:
      - change the maximun function arguments to 14 from 12
      - add testcases (Jiri Olsa)
      - instead EMIT4 with EMIT3_off32 for "lea" to prevent overflow
      ====================
      
      Link: https://lore.kernel.org/r/20230713040738.1789742-1-imagedong@tencent.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      f892cac2