1. 25 5月, 2019 1 次提交
    • J
      selftests: bpf: adjust several test_verifier helpers for insn insertion · f3b55abb
      Jiong Wang 提交于
      - bpf_fill_ld_abs_vlan_push_pop:
          Prevent zext happens inside PUSH_CNT loop. This could happen because
          of BPF_LD_ABS (32-bit def) + BPF_JMP (64-bit use), or BPF_LD_ABS +
          EXIT (64-bit use of R0). So, change BPF_JMP to BPF_JMP32 and redefine
          R0 at exit path to cut off the data-flow from inside the loop.
      
        - bpf_fill_jump_around_ld_abs:
          Jump range is limited to 16 bit. every ld_abs is replaced by 6 insns,
          but on arches like arm, ppc etc, there will be one BPF_ZEXT inserted
          to extend the error value of the inlined ld_abs sequence which then
          contains 7 insns. so, set the dividend to 7 so the testcase could
          work on all arches.
      
        - bpf_fill_scale1/bpf_fill_scale2:
          Both contains ~1M BPF_ALU32_IMM which will trigger ~1M insn patcher
          call because of hi32 randomization later when BPF_F_TEST_RND_HI32 is
          set for bpf selftests. Insn patcher is not efficient that 1M call to
          it will hang computer. So , change to BPF_ALU64_IMM to avoid hi32
          randomization.
      Signed-off-by: NJiong Wang <jiong.wang@netronome.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      f3b55abb
  2. 23 5月, 2019 1 次提交
  3. 28 4月, 2019 1 次提交
  4. 19 4月, 2019 1 次提交
  5. 16 4月, 2019 1 次提交
  6. 10 4月, 2019 1 次提交
  7. 04 4月, 2019 1 次提交
  8. 22 3月, 2019 1 次提交
  9. 02 2月, 2019 1 次提交
  10. 31 1月, 2019 2 次提交
  11. 28 1月, 2019 3 次提交
  12. 27 1月, 2019 1 次提交
  13. 24 1月, 2019 2 次提交
  14. 06 1月, 2019 1 次提交
  15. 03 1月, 2019 1 次提交
  16. 22 12月, 2018 1 次提交
  17. 21 12月, 2018 3 次提交
  18. 19 12月, 2018 2 次提交
  19. 15 12月, 2018 2 次提交
  20. 14 12月, 2018 1 次提交
    • J
      bpf: verifier: make sure callees don't prune with caller differences · 7640ead9
      Jakub Kicinski 提交于
      Currently for liveness and state pruning the register parentage
      chains don't include states of the callee.  This makes some sense
      as the callee can't access those registers.  However, this means
      that READs done after the callee returns will not propagate into
      the states of the callee.  Callee will then perform pruning
      disregarding differences in caller state.
      
      Example:
      
         0: (85) call bpf_user_rnd_u32
         1: (b7) r8 = 0
         2: (55) if r0 != 0x0 goto pc+1
         3: (b7) r8 = 1
         4: (bf) r1 = r8
         5: (85) call pc+4
         6: (15) if r8 == 0x1 goto pc+1
         7: (05) *(u64 *)(r9 - 8) = r3
         8: (b7) r0 = 0
         9: (95) exit
      
         10: (15) if r1 == 0x0 goto pc+0
         11: (95) exit
      
      Here we acquire unknown state with call to get_random() [1].  Then
      we store this random state in r8 (either 0 or 1) [1 - 3], and make
      a call on line 5.  Callee does nothing but a trivial conditional
      jump (to create a pruning point).  Upon return caller checks the
      state of r8 and either performs an unsafe read or not.
      
      Verifier will first explore the path with r8 == 1, creating a pruning
      point at [11].  The parentage chain for r8 will include only callers
      states so once verifier reaches [6] it will mark liveness only on states
      in the caller, and not [11].  Now when verifier walks the paths with
      r8 == 0 it will reach [11] and since REG_LIVE_READ on r8 was not
      propagated there it will prune the walk entirely (stop walking
      the entire program, not just the callee).  Since [6] was never walked
      with r8 == 0, [7] will be considered dead and replaced with "goto -1"
      causing hang at runtime.
      
      This patch weaves the callee's explored states onto the callers
      parentage chain.  Rough parentage for r8 would have looked like this
      before:
      
      [0] [1] [2] [3] [4] [5]   [10]      [11]      [6]      [7]
           |           |      ,---|----.    |        |        |
        sl0:         sl0:    / sl0:     \ sl0:      sl0:     sl0:
        fr0: r8 <-- fr0: r8<+--fr0: r8   `fr0: r8  ,fr0: r8<-fr0: r8
                             \ fr1: r8 <- fr1: r8 /
                              \__________________/
      
      after:
      
      [0] [1] [2] [3] [4] [5]   [10]      [11]      [6]      [7]
           |           |          |         |        |        |
         sl0:         sl0:      sl0:       sl0:      sl0:     sl0:
         fr0: r8 <-- fr0: r8 <- fr0: r8 <- fr0: r8 <-fr0: r8<-fr0: r8
                                fr1: r8 <- fr1: r8
      
      Now the mark from instruction 6 will travel through callees states.
      
      Note that we don't have to connect r0 because its overwritten by
      callees state on return and r1 - r5 because those are not alive
      any more once a call is made.
      
      v2:
       - don't connect the callees registers twice (Alexei: suggestion & code)
       - add more details to the comment (Ed & Alexei)
      v1: don't unnecessarily link caller saved regs (Jiong)
      
      Fixes: f4d7e40a ("bpf: introduce function calls (verification)")
      Reported-by: NDavid Beckett <david.beckett@netronome.com>
      Signed-off-by: NJakub Kicinski <jakub.kicinski@netronome.com>
      Reviewed-by: NJiong Wang <jiong.wang@netronome.com>
      Reviewed-by: NEdward Cree <ecree@solarflare.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      7640ead9
  21. 11 12月, 2018 3 次提交
    • S
      selftests/bpf: use proper type when passing prog_type · aca1a80e
      Stanislav Fomichev 提交于
      Use bpf_prog_type instead of bpf_map_type when passing prog_type.
      
      -Wenum-conversion might be unhappy about it:
      	error: implicit conversion from enumeration type
      	'enum bpf_map_type' to different enumeration type
      	'enum bpf_prog_type'
      Signed-off-by: NStanislav Fomichev <sdf@google.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      aca1a80e
    • S
      selftests/bpf: add missing pointer dereference for map stacktrace fixup · c2a20a27
      Stanislav Fomichev 提交于
      I get a segfault without it, other fixups always do dereference, and
      without dereference I don't understand how it can ever work.
      
      Fixes: 7c85c448 ("selftests/bpf: test_verifier, check bpf_map_lookup_elem access in bpf prog")
      Signed-off-by: NStanislav Fomichev <sdf@google.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      c2a20a27
    • J
      bpf: relax verifier restriction on BPF_MOV | BPF_ALU · e434b8cd
      Jiong Wang 提交于
      Currently, the destination register is marked as unknown for 32-bit
      sub-register move (BPF_MOV | BPF_ALU) whenever the source register type is
      SCALAR_VALUE.
      
      This is too conservative that some valid cases will be rejected.
      Especially, this may turn a constant scalar value into unknown value that
      could break some assumptions of verifier.
      
      For example, test_l4lb_noinline.c has the following C code:
      
          struct real_definition *dst
      
      1:  if (!get_packet_dst(&dst, &pckt, vip_info, is_ipv6))
      2:    return TC_ACT_SHOT;
      3:
      4:  if (dst->flags & F_IPV6) {
      
      get_packet_dst is responsible for initializing "dst" into valid pointer and
      return true (1), otherwise return false (0). The compiled instruction
      sequence using alu32 will be:
      
        412: (54) (u32) r7 &= (u32) 1
        413: (bc) (u32) r0 = (u32) r7
        414: (95) exit
      
      insn 413, a BPF_MOV | BPF_ALU, however will turn r0 into unknown value even
      r7 contains SCALAR_VALUE 1.
      
      This causes trouble when verifier is walking the code path that hasn't
      initialized "dst" inside get_packet_dst, for which case 0 is returned and
      we would then expect verifier concluding line 1 in the above C code pass
      the "if" check, therefore would skip fall through path starting at line 4.
      Now, because r0 returned from callee has became unknown value, so verifier
      won't skip analyzing path starting at line 4 and "dst->flags" requires
      dereferencing the pointer "dst" which actually hasn't be initialized for
      this path.
      
      This patch relaxed the code marking sub-register move destination. For a
      SCALAR_VALUE, it is safe to just copy the value from source then truncate
      it into 32-bit.
      
      A unit test also included to demonstrate this issue. This test will fail
      before this patch.
      
      This relaxation could let verifier skipping more paths for conditional
      comparison against immediate. It also let verifier recording a more
      accurate/strict value for one register at one state, if this state end up
      with going through exit without rejection and it is used for state
      comparison later, then it is possible an inaccurate/permissive value is
      better. So the real impact on verifier processed insn number is complex.
      But in all, without this fix, valid program could be rejected.
      
      >From real benchmarking on kernel selftests and Cilium bpf tests, there is
      no impact on processed instruction number when tests ares compiled with
      default compilation options. There is slightly improvements when they are
      compiled with -mattr=+alu32 after this patch.
      
      Also, test_xdp_noinline/-mattr=+alu32 now passed verification. It is
      rejected before this fix.
      
      Insn processed before/after this patch:
      
                              default     -mattr=+alu32
      
      Kernel selftest
      
      ===
      test_xdp.o              371/371      369/369
      test_l4lb.o             6345/6345    5623/5623
      test_xdp_noinline.o     2971/2971    rejected/2727
      test_tcp_estates.o      429/429      430/430
      
      Cilium bpf
      ===
      bpf_lb-DLB_L3.o:        2085/2085     1685/1687
      bpf_lb-DLB_L4.o:        2287/2287     1986/1982
      bpf_lb-DUNKNOWN.o:      690/690       622/622
      bpf_lxc.o:              95033/95033   N/A
      bpf_netdev.o:           7245/7245     N/A
      bpf_overlay.o:          2898/2898     3085/2947
      
      NOTE:
        - bpf_lxc.o and bpf_netdev.o compiled by -mattr=+alu32 are rejected by
          verifier due to another issue inside verifier on supporting alu32
          binary.
        - Each cilium bpf program could generate several processed insn number,
          above number is sum of them.
      
      v1->v2:
       - Restrict the change on SCALAR_VALUE.
       - Update benchmark numbers on Cilium bpf tests.
      Signed-off-by: NJiong Wang <jiong.wang@netronome.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      e434b8cd
  22. 08 12月, 2018 1 次提交
  23. 05 12月, 2018 1 次提交
    • A
      bpf: improve verifier branch analysis · 4f7b3e82
      Alexei Starovoitov 提交于
      pathological bpf programs may try to force verifier to explode in
      the number of branch states:
        20: (d5) if r1 s<= 0x24000028 goto pc+0
        21: (b5) if r0 <= 0xe1fa20 goto pc+2
        22: (d5) if r1 s<= 0x7e goto pc+0
        23: (b5) if r0 <= 0xe880e000 goto pc+0
        24: (c5) if r0 s< 0x2100ecf4 goto pc+0
        25: (d5) if r1 s<= 0xe880e000 goto pc+1
        26: (c5) if r0 s< 0xf4041810 goto pc+0
        27: (d5) if r1 s<= 0x1e007e goto pc+0
        28: (b5) if r0 <= 0xe86be000 goto pc+0
        29: (07) r0 += 16614
        30: (c5) if r0 s< 0x6d0020da goto pc+0
        31: (35) if r0 >= 0x2100ecf4 goto pc+0
      
      Teach verifier to recognize always taken and always not taken branches.
      This analysis is already done for == and != comparison.
      Expand it to all other branches.
      
      It also helps real bpf programs to be verified faster:
                             before  after
      bpf_lb-DLB_L3.o         2003    1940
      bpf_lb-DLB_L4.o         3173    3089
      bpf_lb-DUNKNOWN.o       1080    1065
      bpf_lxc-DDROP_ALL.o     29584   28052
      bpf_lxc-DUNKNOWN.o      36916   35487
      bpf_netdev.o            11188   10864
      bpf_overlay.o           6679    6643
      bpf_lcx_jit.o           39555   38437
      Reported-by: NAnatoly Trosinenko <anatoly.trosinenko@gmail.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NEdward Cree <ecree@solarflare.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      4f7b3e82
  24. 04 12月, 2018 1 次提交
  25. 01 12月, 2018 6 次提交