1. 06 Jul, 2022 3 commits
  2. 05 Jul, 2022 7 commits
  3. 04 Jul, 2022 20 commits
  4. 03 Jul, 2022 1 commit
    • David S. Miller's avatar
      Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf · 280e3a85
      David S. Miller authored
      Pablo Neira Ayuso says:
      
      ====================
      Netfilter fixes for net
      
      The following patchset contains Netfilter fixes for net:
      
      1) Insufficient validation of element datatype and length in
         nft_setelem_parse_data(). At least commit 7d740264 updates
         maximum element data area up to 64 bytes when only 16 bytes
         where supported at the time. Support for larger element size
         came later in fdb9c405 though. Picking this older commit
         as Fixes: tag to be safe than sorry.
      
      2) Memleak in pipapo destroy path, reproducible when transaction
         in aborted. This is already triggering in the existing netfilter
         test infrastructure since more recent new tests are covering this
         path.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      280e3a85
  5. 02 Jul, 2022 5 commits
  6. 01 Jul, 2022 4 commits
    • Daniel Borkmann's avatar
      bpf, selftests: Add verifier test case for jmp32's jeq/jne · a49b8ce7
      Daniel Borkmann authored
      Add a test case to trigger the verifier's incorrect conclusion in the
      case of jmp32's jeq/jne. Also here, make use of dead code elimination,
      so that we can see the verifier bailing out on unfixed kernels.
      
      Before:
      
        # ./test_verifier 724
        #724/p jeq32/jne32: bounds checking FAIL
        Failed to load prog 'Permission denied'!
        R4 !read_ok
        verification time 8 usec
        stack depth 0
        processed 8 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 0
        Summary: 0 PASSED, 0 SKIPPED, 1 FAILED
      
      After:
      
        # ./test_verifier 724
        #724/p jeq32/jne32: bounds checking OK
        Summary: 1 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20220701124727.11153-4-daniel@iogearbox.net
      a49b8ce7
    • Daniel Borkmann's avatar
      bpf, selftests: Add verifier test case for imm=0,umin=0,umax=1 scalar · 73c4936f
      Daniel Borkmann authored
      Add a test case to trigger the constant scalar issue which leaves the
      register in scalar(imm=0,umin=0,umax=1,var_off=(0x0; 0x0)) state. Make
      use of dead code elimination, so that we can see the verifier bailing
      out on unfixed kernels. For the condition, we use jle given it checks
      on umax bound.
      
      Before:
      
        # ./test_verifier 743
        #743/p jump & dead code elimination FAIL
        Failed to load prog 'Permission denied'!
        R4 !read_ok
        verification time 11 usec
        stack depth 0
        processed 13 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
        Summary: 0 PASSED, 0 SKIPPED, 1 FAILED
      
      After:
      
        # ./test_verifier 743
        #743/p jump & dead code elimination OK
        Summary: 1 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20220701124727.11153-3-daniel@iogearbox.net
      73c4936f
    • Daniel Borkmann's avatar
      bpf: Fix insufficient bounds propagation from adjust_scalar_min_max_vals · 3844d153
      Daniel Borkmann authored
      Kuee reported a corner case where the tnum becomes constant after the call
      to __reg_bound_offset(), but the register's bounds are not, that is, its
      min bounds are still not equal to the register's max bounds.
      
      This in turn allows to leak pointers through turning a pointer register as
      is into an unknown scalar via adjust_ptr_min_max_vals().
      
      Before:
      
        func#0 @0
        0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        0: (b7) r0 = 1                        ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0))
        1: (b7) r3 = 0                        ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0))
        2: (87) r3 = -r3                      ; R3_w=scalar()
        3: (87) r3 = -r3                      ; R3_w=scalar()
        4: (47) r3 |= 32767                   ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881)
        5: (75) if r3 s>= 0x0 goto pc+1       ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)
        6: (95) exit
      
        from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        7: (d5) if r3 s<= 0x8000 goto pc+1    ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)
        8: (95) exit
      
        from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        9: (07) r3 += -32767                  ; R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0))  <--- [*]
        10: (95) exit
      
      What can be seen here is that R3=scalar(umin=32767,umax=32768,var_off=(0x7fff;
      0x8000)) after the operation R3 += -32767 results in a 'malformed' constant, that
      is, R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0)). Intersecting with var_off has
      not been done at that point via __update_reg_bounds(), which would have improved
      the umax to be equal to umin.
      
      Refactor the tnum <> min/max bounds information flow into a reg_bounds_sync()
      helper and use it consistently everywhere. After the fix, bounds have been
      corrected to R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) and thus the register
      is regarded as a 'proper' constant scalar of 0.
      
      After:
      
        func#0 @0
        0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        0: (b7) r0 = 1                        ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0))
        1: (b7) r3 = 0                        ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0))
        2: (87) r3 = -r3                      ; R3_w=scalar()
        3: (87) r3 = -r3                      ; R3_w=scalar()
        4: (47) r3 |= 32767                   ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881)
        5: (75) if r3 s>= 0x0 goto pc+1       ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)
        6: (95) exit
      
        from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        7: (d5) if r3 s<= 0x8000 goto pc+1    ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767)
        8: (95) exit
      
        from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0))
        9: (07) r3 += -32767                  ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0))  <--- [*]
        10: (95) exit
      
      Fixes: b03c9f9f ("bpf/verifier: track signed and unsigned min/max values")
      Reported-by: default avatarKuee K1r0a <liulin063@gmail.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20220701124727.11153-2-daniel@iogearbox.net
      3844d153
    • Daniel Borkmann's avatar
      bpf: Fix incorrect verifier simulation around jmp32's jeq/jne · a12ca627
      Daniel Borkmann authored
      Kuee reported a quirk in the jmp32's jeq/jne simulation, namely that the
      register value does not match expectations for the fall-through path. For
      example:
      
      Before fix:
      
        0: R1=ctx(off=0,imm=0) R10=fp0
        0: (b7) r2 = 0                        ; R2_w=P0
        1: (b7) r6 = 563                      ; R6_w=P563
        2: (87) r2 = -r2                      ; R2_w=Pscalar()
        3: (87) r2 = -r2                      ; R2_w=Pscalar()
        4: (4c) w2 |= w6                      ; R2_w=Pscalar(umin=563,umax=4294967295,var_off=(0x233; 0xfffffdcc),s32_min=-2147483085) R6_w=P563
        5: (56) if w2 != 0x8 goto pc+1        ; R2_w=P571  <--- [*]
        6: (95) exit
        R0 !read_ok
      
      After fix:
      
        0: R1=ctx(off=0,imm=0) R10=fp0
        0: (b7) r2 = 0                        ; R2_w=P0
        1: (b7) r6 = 563                      ; R6_w=P563
        2: (87) r2 = -r2                      ; R2_w=Pscalar()
        3: (87) r2 = -r2                      ; R2_w=Pscalar()
        4: (4c) w2 |= w6                      ; R2_w=Pscalar(umin=563,umax=4294967295,var_off=(0x233; 0xfffffdcc),s32_min=-2147483085) R6_w=P563
        5: (56) if w2 != 0x8 goto pc+1        ; R2_w=P8  <--- [*]
        6: (95) exit
        R0 !read_ok
      
      As can be seen on line 5 for the branch fall-through path in R2 [*] is that
      given condition w2 != 0x8 is false, verifier should conclude that r2 = 8 as
      upper 32 bit are known to be zero. However, verifier incorrectly concludes
      that r2 = 571 which is far off.
      
      The problem is it only marks false{true}_reg as known in the switch for JE/NE
      case, but at the end of the function, it uses {false,true}_{64,32}off to
      update {false,true}_reg->var_off and they still hold the prior value of
      {false,true}_reg->var_off before it got marked as known. The subsequent
      __reg_combine_32_into_64() then propagates this old var_off and derives new
      bounds. The information between min/max bounds on {false,true}_reg from
      setting the register to known const combined with the {false,true}_reg->var_off
      based on the old information then derives wrong register data.
      
      Fix it by detangling the BPF_JEQ/BPF_JNE cases and updating relevant
      {false,true}_{64,32}off tnums along with the register marking to known
      constant.
      
      Fixes: 3f50f132 ("bpf: Verifier, do explicit ALU32 bounds tracking")
      Reported-by: default avatarKuee K1r0a <liulin063@gmail.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20220701124727.11153-1-daniel@iogearbox.net
      a12ca627