1. 18 Dec, 2021 4 commits
    • Hao Luo's avatar
      bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL · c25b2ae1
      Hao Luo authored
      We have introduced a new type to make bpf_reg composable, by
      allocating bits in the type to represent flags.
      
      One of the flags is PTR_MAYBE_NULL which indicates a pointer
      may be NULL. This patch switches the qualified reg_types to
      use this flag. The reg_types changed in this patch include:
      
      1. PTR_TO_MAP_VALUE_OR_NULL
      2. PTR_TO_SOCKET_OR_NULL
      3. PTR_TO_SOCK_COMMON_OR_NULL
      4. PTR_TO_TCP_SOCK_OR_NULL
      5. PTR_TO_BTF_ID_OR_NULL
      6. PTR_TO_MEM_OR_NULL
      7. PTR_TO_RDONLY_BUF_OR_NULL
      8. PTR_TO_RDWR_BUF_OR_NULL
      Signed-off-by: default avatarHao Luo <haoluo@google.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/r/20211217003152.48334-5-haoluo@google.com
      c25b2ae1
    • Hao Luo's avatar
      bpf: Replace RET_XXX_OR_NULL with RET_XXX | PTR_MAYBE_NULL · 3c480732
      Hao Luo authored
      We have introduced a new type to make bpf_ret composable, by
      reserving high bits to represent flags.
      
      One of the flag is PTR_MAYBE_NULL, which indicates a pointer
      may be NULL. When applying this flag to ret_types, it means
      the returned value could be a NULL pointer. This patch
      switches the qualified arg_types to use this flag.
      The ret_types changed in this patch include:
      
      1. RET_PTR_TO_MAP_VALUE_OR_NULL
      2. RET_PTR_TO_SOCKET_OR_NULL
      3. RET_PTR_TO_TCP_SOCK_OR_NULL
      4. RET_PTR_TO_SOCK_COMMON_OR_NULL
      5. RET_PTR_TO_ALLOC_MEM_OR_NULL
      6. RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL
      7. RET_PTR_TO_BTF_ID_OR_NULL
      
      This patch doesn't eliminate the use of these names, instead
      it makes them aliases to 'RET_PTR_TO_XXX | PTR_MAYBE_NULL'.
      Signed-off-by: default avatarHao Luo <haoluo@google.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211217003152.48334-4-haoluo@google.com
      3c480732
    • Hao Luo's avatar
      bpf: Replace ARG_XXX_OR_NULL with ARG_XXX | PTR_MAYBE_NULL · 48946bd6
      Hao Luo authored
      We have introduced a new type to make bpf_arg composable, by
      reserving high bits of bpf_arg to represent flags of a type.
      
      One of the flags is PTR_MAYBE_NULL which indicates a pointer
      may be NULL. When applying this flag to an arg_type, it means
      the arg can take NULL pointer. This patch switches the
      qualified arg_types to use this flag. The arg_types changed
      in this patch include:
      
      1. ARG_PTR_TO_MAP_VALUE_OR_NULL
      2. ARG_PTR_TO_MEM_OR_NULL
      3. ARG_PTR_TO_CTX_OR_NULL
      4. ARG_PTR_TO_SOCKET_OR_NULL
      5. ARG_PTR_TO_ALLOC_MEM_OR_NULL
      6. ARG_PTR_TO_STACK_OR_NULL
      
      This patch does not eliminate the use of these arg_types, instead
      it makes them an alias to the 'ARG_XXX | PTR_MAYBE_NULL'.
      Signed-off-by: default avatarHao Luo <haoluo@google.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211217003152.48334-3-haoluo@google.com
      48946bd6
    • Hao Luo's avatar
      bpf: Introduce composable reg, ret and arg types. · d639b9d1
      Hao Luo authored
      There are some common properties shared between bpf reg, ret and arg
      values. For instance, a value may be a NULL pointer, or a pointer to
      a read-only memory. Previously, to express these properties, enumeration
      was used. For example, in order to test whether a reg value can be NULL,
      reg_type_may_be_null() simply enumerates all types that are possibly
      NULL. The problem of this approach is that it's not scalable and causes
      a lot of duplication. These properties can be combined, for example, a
      type could be either MAYBE_NULL or RDONLY, or both.
      
      This patch series rewrites the layout of reg_type, arg_type and
      ret_type, so that common properties can be extracted and represented as
      composable flag. For example, one can write
      
       ARG_PTR_TO_MEM | PTR_MAYBE_NULL
      
      which is equivalent to the previous
      
       ARG_PTR_TO_MEM_OR_NULL
      
      The type ARG_PTR_TO_MEM are called "base type" in this patch. Base
      types can be extended with flags. A flag occupies the higher bits while
      base types sits in the lower bits.
      
      This patch in particular sets up a set of macro for this purpose. The
      following patches will rewrite arg_types, ret_types and reg_types
      respectively.
      Signed-off-by: default avatarHao Luo <haoluo@google.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211217003152.48334-2-haoluo@google.com
      d639b9d1
  2. 17 Dec, 2021 6 commits
    • Andrii Nakryiko's avatar
      bpftool: Reimplement large insn size limit feature probing · e967a20a
      Andrii Nakryiko authored
      Reimplement bpf_probe_large_insn_limit() in bpftool, as that libbpf API
      is scheduled for deprecation in v0.8.
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
      Link: https://lore.kernel.org/bpf/20211217171202.3352835-4-andrii@kernel.org
      e967a20a
    • Andrii Nakryiko's avatar
      selftests/bpf: Add libbpf feature-probing API selftests · 5a8ea82f
      Andrii Nakryiko authored
      Add selftests for prog/map/prog+helper feature probing APIs. Prog and
      map selftests are designed in such a way that they will always test all
      the possible prog/map types, based on running kernel's vmlinux BTF enum
      definition. This way we'll always be sure that when adding new BPF
      program types or map types, libbpf will be always updated accordingly to
      be able to feature-detect them.
      
      BPF prog_helper selftest will have to be manually extended with
      interesting and important prog+helper combinations, it's easy, but can't
      be completely automated.
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
      Link: https://lore.kernel.org/bpf/20211217171202.3352835-3-andrii@kernel.org
      5a8ea82f
    • Andrii Nakryiko's avatar
      libbpf: Rework feature-probing APIs · 878d8def
      Andrii Nakryiko authored
      Create three extensible alternatives to inconsistently named
      feature-probing APIs:
      
        - libbpf_probe_bpf_prog_type() instead of bpf_probe_prog_type();
        - libbpf_probe_bpf_map_type() instead of bpf_probe_map_type();
        - libbpf_probe_bpf_helper() instead of bpf_probe_helper().
      
      Set up return values such that libbpf can report errors (e.g., if some
      combination of input arguments isn't possible to validate, etc), in
      addition to whether the feature is supported (return value 1) or not
      supported (return value 0).
      
      Also schedule deprecation of those three APIs. Also schedule deprecation
      of bpf_probe_large_insn_limit().
      
      Also fix all the existing detection logic for various program and map
      types that never worked:
      
        - BPF_PROG_TYPE_LIRC_MODE2;
        - BPF_PROG_TYPE_TRACING;
        - BPF_PROG_TYPE_LSM;
        - BPF_PROG_TYPE_EXT;
        - BPF_PROG_TYPE_SYSCALL;
        - BPF_PROG_TYPE_STRUCT_OPS;
        - BPF_MAP_TYPE_STRUCT_OPS;
        - BPF_MAP_TYPE_BLOOM_FILTER.
      
      Above prog/map types needed special setups and detection logic to work.
      Subsequent patch adds selftests that will make sure that all the
      detection logic keeps working for all current and future program and map
      types, avoiding otherwise inevitable bit rot.
      
        [0] Closes: https://github.com/libbpf/libbpf/issues/312Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
      Cc: Julia Kartseva <hex@fb.com>
      Link: https://lore.kernel.org/bpf/20211217171202.3352835-2-andrii@kernel.org
      878d8def
    • Christy Lee's avatar
      Only output backtracking information in log level 2 · 496f3324
      Christy Lee authored
      Backtracking information is very verbose, don't print it in log
      level 1 to improve readability.
      Signed-off-by: default avatarChristy Lee <christylee@fb.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20211216213358.3374427-4-christylee@fb.com
      496f3324
    • Christy Lee's avatar
      bpf: Right align verifier states in verifier logs. · 2e576648
      Christy Lee authored
      Make the verifier logs more readable, print the verifier states
      on the corresponding instruction line. If the previous line was
      not a bpf instruction, then print the verifier states on its own
      line.
      
      Before:
      
      Validating test_pkt_access_subprog3() func#3...
      86: R1=invP(id=0) R2=ctx(id=0,off=0,imm=0) R10=fp0
      ; int test_pkt_access_subprog3(int val, struct __sk_buff *skb)
      86: (bf) r6 = r2
      87: R2=ctx(id=0,off=0,imm=0) R6_w=ctx(id=0,off=0,imm=0)
      87: (bc) w7 = w1
      88: R1=invP(id=0) R7_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
      ; return get_skb_len(skb) * get_skb_ifindex(val, skb, get_constant(123));
      88: (bf) r1 = r6
      89: R1_w=ctx(id=0,off=0,imm=0) R6_w=ctx(id=0,off=0,imm=0)
      89: (85) call pc+9
      Func#4 is global and valid. Skipping.
      90: R0_w=invP(id=0)
      90: (bc) w8 = w0
      91: R0_w=invP(id=0) R8_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
      ; return get_skb_len(skb) * get_skb_ifindex(val, skb, get_constant(123));
      91: (b7) r1 = 123
      92: R1_w=invP123
      92: (85) call pc+65
      Func#5 is global and valid. Skipping.
      93: R0=invP(id=0)
      
      After:
      
      86: R1=invP(id=0) R2=ctx(id=0,off=0,imm=0) R10=fp0
      ; int test_pkt_access_subprog3(int val, struct __sk_buff *skb)
      86: (bf) r6 = r2                      ; R2=ctx(id=0,off=0,imm=0) R6_w=ctx(id=0,off=0,imm=0)
      87: (bc) w7 = w1                      ; R1=invP(id=0) R7_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
      ; return get_skb_len(skb) * get_skb_ifindex(val, skb, get_constant(123));
      88: (bf) r1 = r6                      ; R1_w=ctx(id=0,off=0,imm=0) R6_w=ctx(id=0,off=0,imm=0)
      89: (85) call pc+9
      Func#4 is global and valid. Skipping.
      90: R0_w=invP(id=0)
      90: (bc) w8 = w0                      ; R0_w=invP(id=0) R8_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
      ; return get_skb_len(skb) * get_skb_ifindex(val, skb, get_constant(123));
      91: (b7) r1 = 123                     ; R1_w=invP123
      92: (85) call pc+65
      Func#5 is global and valid. Skipping.
      93: R0=invP(id=0)
      Signed-off-by: default avatarChristy Lee <christylee@fb.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      2e576648
    • Christy Lee's avatar
      bpf: Only print scratched registers and stack slots to verifier logs. · 0f55f9ed
      Christy Lee authored
      When printing verifier state for any log level, print full verifier
      state only on function calls or on errors. Otherwise, only print the
      registers and stack slots that were accessed.
      
      Log size differences:
      
      verif_scale_loop6 before: 234566564
      verif_scale_loop6 after: 72143943
      69% size reduction
      
      kfree_skb before: 166406
      kfree_skb after: 55386
      69% size reduction
      
      Before:
      
      156: (61) r0 = *(u32 *)(r1 +0)
      157: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=ctx(id=0,off=0,imm=0) R2_w=invP0 R10=fp0 fp-8_w=00000000 fp-16_w=00\
      000000 fp-24_w=00000000 fp-32_w=00000000 fp-40_w=00000000 fp-48_w=00000000 fp-56_w=00000000 fp-64_w=00000000 fp-72_w=00000000 fp-80_w=00000\
      000 fp-88_w=00000000 fp-96_w=00000000 fp-104_w=00000000 fp-112_w=00000000 fp-120_w=00000000 fp-128_w=00000000 fp-136_w=00000000 fp-144_w=00\
      000000 fp-152_w=00000000 fp-160_w=00000000 fp-168_w=00000000 fp-176_w=00000000 fp-184_w=00000000 fp-192_w=00000000 fp-200_w=00000000 fp-208\
      _w=00000000 fp-216_w=00000000 fp-224_w=00000000 fp-232_w=00000000 fp-240_w=00000000 fp-248_w=00000000 fp-256_w=00000000 fp-264_w=00000000 f\
      p-272_w=00000000 fp-280_w=00000000 fp-288_w=00000000 fp-296_w=00000000 fp-304_w=00000000 fp-312_w=00000000 fp-320_w=00000000 fp-328_w=00000\
      000 fp-336_w=00000000 fp-344_w=00000000 fp-352_w=00000000 fp-360_w=00000000 fp-368_w=00000000 fp-376_w=00000000 fp-384_w=00000000 fp-392_w=\
      00000000 fp-400_w=00000000 fp-408_w=00000000 fp-416_w=00000000 fp-424_w=00000000 fp-432_w=00000000 fp-440_w=00000000 fp-448_w=00000000
      ; return skb->len;
      157: (95) exit
      Func#4 is safe for any args that match its prototype
      Validating get_constant() func#5...
      158: R1=invP(id=0) R10=fp0
      ; int get_constant(long val)
      158: (bf) r0 = r1
      159: R0_w=invP(id=1) R1=invP(id=1) R10=fp0
      ; return val - 122;
      159: (04) w0 += -122
      160: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=invP(id=1) R10=fp0
      ; return val - 122;
      160: (95) exit
      Func#5 is safe for any args that match its prototype
      Validating get_skb_ifindex() func#6...
      161: R1=invP(id=0) R2=ctx(id=0,off=0,imm=0) R3=invP(id=0) R10=fp0
      ; int get_skb_ifindex(int val, struct __sk_buff *skb, int var)
      161: (bc) w0 = w3
      162: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=invP(id=0) R2=ctx(id=0,off=0,imm=0) R3=invP(id=0) R10=fp0
      
      After:
      
      156: (61) r0 = *(u32 *)(r1 +0)
      157: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R1=ctx(id=0,off=0,imm=0)
      ; return skb->len;
      157: (95) exit
      Func#4 is safe for any args that match its prototype
      Validating get_constant() func#5...
      158: R1=invP(id=0) R10=fp0
      ; int get_constant(long val)
      158: (bf) r0 = r1
      159: R0_w=invP(id=1) R1=invP(id=1)
      ; return val - 122;
      159: (04) w0 += -122
      160: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff))
      ; return val - 122;
      160: (95) exit
      Func#5 is safe for any args that match its prototype
      Validating get_skb_ifindex() func#6...
      161: R1=invP(id=0) R2=ctx(id=0,off=0,imm=0) R3=invP(id=0) R10=fp0
      ; int get_skb_ifindex(int val, struct __sk_buff *skb, int var)
      161: (bc) w0 = w3
      162: R0_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R3=invP(id=0)
      Signed-off-by: default avatarChristy Lee <christylee@fb.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20211216213358.3374427-2-christylee@fb.com
      0f55f9ed
  3. 16 Dec, 2021 11 commits
  4. 15 Dec, 2021 1 commit
  5. 14 Dec, 2021 9 commits
  6. 13 Dec, 2021 9 commits