1. 03 10月, 2018 3 次提交
  2. 01 10月, 2018 1 次提交
    • R
      selftests/bpf: add verifier per-cpu cgroup storage tests · a3c6054f
      Roman Gushchin 提交于
      This commits adds verifier tests covering per-cpu cgroup storage
      functionality. There are 6 new tests, which are exactly the same
      as for shared cgroup storage, but do use per-cpu cgroup storage
      map.
      
      Expected output:
        $ ./test_verifier
        #0/u add+sub+mul OK
        #0/p add+sub+mul OK
        ...
        #286/p invalid cgroup storage access 6 OK
        #287/p valid per-cpu cgroup storage access OK
        #288/p invalid per-cpu cgroup storage access 1 OK
        #289/p invalid per-cpu cgroup storage access 2 OK
        #290/p invalid per-cpu cgroup storage access 3 OK
        #291/p invalid per-cpu cgroup storage access 4 OK
        #292/p invalid per-cpu cgroup storage access 5 OK
        #293/p invalid per-cpu cgroup storage access 6 OK
        #294/p multiple registers share map_lookup_elem result OK
        ...
        #662/p mov64 src == dst OK
        #663/p mov64 src != dst OK
        Summary: 914 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: NRoman Gushchin <guro@fb.com>
      Acked-by: NSong Liu <songliubraving@fb.com>
      Cc: Daniel Borkmann <daniel@iogearbox.net>
      Cc: Alexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      a3c6054f
  3. 11 8月, 2018 1 次提交
  4. 03 8月, 2018 2 次提交
    • R
      selftests/bpf: fix a typo in map in map test · 0069fb85
      Roman Gushchin 提交于
      Commit fbeb1603 ("bpf: verifier: MOV64 don't mark dst reg unbounded")
      revealed a typo in commit fb30d4b7 ("bpf: Add tests for map-in-map"):
      BPF_MOV64_REG(BPF_REG_0, 0) was used instead of
      BPF_MOV64_IMM(BPF_REG_0, 0).
      
      I've noticed the problem by running bpf kselftests.
      
      Fixes: fb30d4b7 ("bpf: Add tests for map-in-map")
      Signed-off-by: NRoman Gushchin <guro@fb.com>
      Cc: Martin KaFai Lau <kafai@fb.com>
      Cc: Arthur Fabre <afabre@cloudflare.com>
      Cc: Daniel Borkmann <daniel@iogearbox.net>
      Cc: Alexei Starovoitov <ast@kernel.org>
      Acked-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      0069fb85
    • R
      selftests/bpf: add verifier cgroup storage tests · d4c9f573
      Roman Gushchin 提交于
      Add the following verifier tests to cover the cgroup storage
      functionality:
      1) valid access to the cgroup storage
      2) invalid access: use regular hashmap instead of cgroup storage map
      3) invalid access: use invalid map fd
      4) invalid access: try access memory after the cgroup storage
      5) invalid access: try access memory before the cgroup storage
      6) invalid access: call get_local_storage() with non-zero flags
      
      For tests 2)-6) check returned error strings.
      
      Expected output:
        $ ./test_verifier
        #0/u add+sub+mul OK
        #0/p add+sub+mul OK
        #1/u DIV32 by 0, zero check 1 OK
        ...
        #280/p valid cgroup storage access OK
        #281/p invalid cgroup storage access 1 OK
        #282/p invalid cgroup storage access 2 OK
        #283/p invalid per-cgroup storage access 3 OK
        #284/p invalid cgroup storage access 4 OK
        #285/p invalid cgroup storage access 5 OK
        ...
        #649/p pass modified ctx pointer to helper, 2 OK
        #650/p pass modified ctx pointer to helper, 3 OK
        Summary: 901 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: NRoman Gushchin <guro@fb.com>
      Cc: Alexei Starovoitov <ast@kernel.org>
      Cc: Daniel Borkmann <daniel@iogearbox.net>
      Acked-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      d4c9f573
  5. 01 8月, 2018 1 次提交
    • A
      bpf: verifier: MOV64 don't mark dst reg unbounded · fbeb1603
      Arthur Fabre 提交于
      When check_alu_op() handles a BPF_MOV64 between two registers,
      it calls check_reg_arg(DST_OP) on the dst register, marking it
      as unbounded. If the src and dst register are the same, this
      marks the src as unbounded, which can lead to unexpected errors
      for further checks that rely on bounds info. For example:
      
      	BPF_MOV64_IMM(BPF_REG_2, 0),
      	BPF_MOV64_REG(BPF_REG_2, BPF_REG_2),
      	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
      	BPF_MOV64_IMM(BPF_REG_0, 0),
      	BPF_EXIT_INSN(),
      
      Results in:
      
      	"math between ctx pointer and register with unbounded
      	min value is not allowed"
      
      check_alu_op() now uses check_reg_arg(DST_OP_NO_MARK), and MOVs
      that need to mark the dst register (MOVIMM, MOV32) do so.
      
      Added a test case for MOV64 dst == src, and dst != src.
      Signed-off-by: NArthur Fabre <afabre@cloudflare.com>
      Acked-by: NEdward Cree <ecree@solarflare.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      fbeb1603
  6. 20 7月, 2018 1 次提交
  7. 12 7月, 2018 1 次提交
    • D
      bpf: fix panic due to oob in bpf_prog_test_run_skb · 6e6fddc7
      Daniel Borkmann 提交于
      sykzaller triggered several panics similar to the below:
      
        [...]
        [  248.851531] BUG: KASAN: use-after-free in _copy_to_user+0x5c/0x90
        [  248.857656] Read of size 985 at addr ffff8808017ffff2 by task a.out/1425
        [...]
        [  248.865902] CPU: 1 PID: 1425 Comm: a.out Not tainted 4.18.0-rc4+ #13
        [  248.865903] Hardware name: Supermicro SYS-5039MS-H12TRF/X11SSE-F, BIOS 2.1a 03/08/2018
        [  248.865905] Call Trace:
        [  248.865910]  dump_stack+0xd6/0x185
        [  248.865911]  ? show_regs_print_info+0xb/0xb
        [  248.865913]  ? printk+0x9c/0xc3
        [  248.865915]  ? kmsg_dump_rewind_nolock+0xe4/0xe4
        [  248.865919]  print_address_description+0x6f/0x270
        [  248.865920]  kasan_report+0x25b/0x380
        [  248.865922]  ? _copy_to_user+0x5c/0x90
        [  248.865924]  check_memory_region+0x137/0x190
        [  248.865925]  kasan_check_read+0x11/0x20
        [  248.865927]  _copy_to_user+0x5c/0x90
        [  248.865930]  bpf_test_finish.isra.8+0x4f/0xc0
        [  248.865932]  bpf_prog_test_run_skb+0x6a0/0xba0
        [...]
      
      After scrubbing the BPF prog a bit from the noise, turns out it called
      bpf_skb_change_head() for the lwt_xmit prog with headroom of 2. Nothing
      wrong in that, however, this was run with repeat >> 0 in bpf_prog_test_run_skb()
      and the same skb thus keeps changing until the pskb_expand_head() called
      from skb_cow() keeps bailing out in atomic alloc context with -ENOMEM.
      So upon return we'll basically have 0 headroom left yet blindly do the
      __skb_push() of 14 bytes and keep copying data from there in bpf_test_finish()
      out of bounds. Fix to check if we have enough headroom and if pskb_expand_head()
      fails, bail out with error.
      
      Another bug independent of this fix (but related in triggering above) is
      that BPF_PROG_TEST_RUN should be reworked to reset the skb/xdp buffer to
      it's original state from input as otherwise repeating the same test in a
      loop won't work for benchmarking when underlying input buffer is getting
      changed by the prog each time and reused for the next run leading to
      unexpected results.
      
      Fixes: 1cf1cae9 ("bpf: introduce BPF_PROG_TEST_RUN command")
      Reported-by: syzbot+709412e651e55ed96498@syzkaller.appspotmail.com
      Reported-by: syzbot+54f39d6ab58f39720a55@syzkaller.appspotmail.com
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      6e6fddc7
  8. 08 6月, 2018 1 次提交
    • D
      bpf: reject passing modified ctx to helper functions · 58990d1f
      Daniel Borkmann 提交于
      As commit 28e33f9d ("bpf: disallow arithmetic operations on
      context pointer") already describes, f1174f77 ("bpf/verifier:
      rework value tracking") removed the specific white-listed cases
      we had previously where we would allow for pointer arithmetic in
      order to further generalize it, and allow e.g. context access via
      modified registers. While the dereferencing of modified context
      pointers had been forbidden through 28e33f9d, syzkaller did
      recently manage to trigger several KASAN splats for slab out of
      bounds access and use after frees by simply passing a modified
      context pointer to a helper function which would then do the bad
      access since verifier allowed it in adjust_ptr_min_max_vals().
      
      Rejecting arithmetic on ctx pointer in adjust_ptr_min_max_vals()
      generally could break existing programs as there's a valid use
      case in tracing in combination with passing the ctx to helpers as
      bpf_probe_read(), where the register then becomes unknown at
      verification time due to adding a non-constant offset to it. An
      access sequence may look like the following:
      
        offset = args->filename;  /* field __data_loc filename */
        bpf_probe_read(&dst, len, (char *)args + offset); // args is ctx
      
      There are two options: i) we could special case the ctx and as
      soon as we add a constant or bounded offset to it (hence ctx type
      wouldn't change) we could turn the ctx into an unknown scalar, or
      ii) we generalize the sanity test for ctx member access into a
      small helper and assert it on the ctx register that was passed
      as a function argument. Fwiw, latter is more obvious and less
      complex at the same time, and one case that may potentially be
      legitimate in future for ctx member access at least would be for
      ctx to carry a const offset. Therefore, fix follows approach
      from ii) and adds test cases to BPF kselftests.
      
      Fixes: f1174f77 ("bpf/verifier: rework value tracking")
      Reported-by: syzbot+3d0b2441dbb71751615e@syzkaller.appspotmail.com
      Reported-by: syzbot+c8504affd4fdd0c1b626@syzkaller.appspotmail.com
      Reported-by: syzbot+e5190cb881d8660fb1a3@syzkaller.appspotmail.com
      Reported-by: syzbot+efae31b384d5badbd620@syzkaller.appspotmail.com
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NYonghong Song <yhs@fb.com>
      Acked-by: NEdward Cree <ecree@solarflare.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      58990d1f
  9. 03 6月, 2018 1 次提交
  10. 19 5月, 2018 1 次提交
  11. 18 5月, 2018 1 次提交
  12. 15 5月, 2018 1 次提交
  13. 04 5月, 2018 1 次提交
    • D
      bpf: migrate ebpf ld_abs/ld_ind tests to test_verifier · 93731ef0
      Daniel Borkmann 提交于
      Remove all eBPF tests involving LD_ABS/LD_IND from test_bpf.ko. Reason
      is that the eBPF tests from test_bpf module do not go via BPF verifier
      and therefore any instruction rewrites from verifier cannot take place.
      
      Therefore, move them into test_verifier which runs out of user space,
      so that verfier can rewrite LD_ABS/LD_IND internally in upcoming patches.
      It will have the same effect since runtime tests are also performed from
      there. This also allows to finally unexport bpf_skb_vlan_{push,pop}_proto
      and keep it internal to core kernel.
      
      Additionally, also add further cBPF LD_ABS/LD_IND test coverage into
      test_bpf.ko suite.
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      93731ef0
  14. 29 4月, 2018 1 次提交
  15. 25 4月, 2018 1 次提交
  16. 20 3月, 2018 1 次提交
  17. 27 2月, 2018 2 次提交
  18. 24 2月, 2018 2 次提交
    • D
      bpf: add various jit test cases · 23d191a8
      Daniel Borkmann 提交于
      Add few test cases that check the rnu-time results under JIT.
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      23d191a8
    • D
      bpf: allow xadd only on aligned memory · ca369602
      Daniel Borkmann 提交于
      The requirements around atomic_add() / atomic64_add() resp. their
      JIT implementations differ across architectures. E.g. while x86_64
      seems just fine with BPF's xadd on unaligned memory, on arm64 it
      triggers via interpreter but also JIT the following crash:
      
        [  830.864985] Unable to handle kernel paging request at virtual address ffff8097d7ed6703
        [...]
        [  830.916161] Internal error: Oops: 96000021 [#1] SMP
        [  830.984755] CPU: 37 PID: 2788 Comm: test_verifier Not tainted 4.16.0-rc2+ #8
        [  830.991790] Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.29 07/17/2017
        [  830.998998] pstate: 80400005 (Nzcv daif +PAN -UAO)
        [  831.003793] pc : __ll_sc_atomic_add+0x4/0x18
        [  831.008055] lr : ___bpf_prog_run+0x1198/0x1588
        [  831.012485] sp : ffff00001ccabc20
        [  831.015786] x29: ffff00001ccabc20 x28: ffff8017d56a0f00
        [  831.021087] x27: 0000000000000001 x26: 0000000000000000
        [  831.026387] x25: 000000c168d9db98 x24: 0000000000000000
        [  831.031686] x23: ffff000008203878 x22: ffff000009488000
        [  831.036986] x21: ffff000008b14e28 x20: ffff00001ccabcb0
        [  831.042286] x19: ffff0000097b5080 x18: 0000000000000a03
        [  831.047585] x17: 0000000000000000 x16: 0000000000000000
        [  831.052885] x15: 0000ffffaeca8000 x14: 0000000000000000
        [  831.058184] x13: 0000000000000000 x12: 0000000000000000
        [  831.063484] x11: 0000000000000001 x10: 0000000000000000
        [  831.068783] x9 : 0000000000000000 x8 : 0000000000000000
        [  831.074083] x7 : 0000000000000000 x6 : 000580d428000000
        [  831.079383] x5 : 0000000000000018 x4 : 0000000000000000
        [  831.084682] x3 : ffff00001ccabcb0 x2 : 0000000000000001
        [  831.089982] x1 : ffff8097d7ed6703 x0 : 0000000000000001
        [  831.095282] Process test_verifier (pid: 2788, stack limit = 0x0000000018370044)
        [  831.102577] Call trace:
        [  831.105012]  __ll_sc_atomic_add+0x4/0x18
        [  831.108923]  __bpf_prog_run32+0x4c/0x70
        [  831.112748]  bpf_test_run+0x78/0xf8
        [  831.116224]  bpf_prog_test_run_xdp+0xb4/0x120
        [  831.120567]  SyS_bpf+0x77c/0x1110
        [  831.123873]  el0_svc_naked+0x30/0x34
        [  831.127437] Code: 97fffe97 17ffffec 00000000 f9800031 (885f7c31)
      
      Reason for this is because memory is required to be aligned. In
      case of BPF, we always enforce alignment in terms of stack access,
      but not when accessing map values or packet data when the underlying
      arch (e.g. arm64) has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS set.
      
      xadd on packet data that is local to us anyway is just wrong, so
      forbid this case entirely. The only place where xadd makes sense in
      fact are map values; xadd on stack is wrong as well, but it's been
      around for much longer. Specifically enforce strict alignment in case
      of xadd, so that we handle this case generically and avoid such crashes
      in the first place.
      
      Fixes: 17a52670 ("bpf: verifier (add verifier core)")
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      ca369602
  19. 23 2月, 2018 1 次提交
    • D
      bpf, arm64: fix out of bounds access in tail call · 16338a9b
      Daniel Borkmann 提交于
      I recently noticed a crash on arm64 when feeding a bogus index
      into BPF tail call helper. The crash would not occur when the
      interpreter is used, but only in case of JIT. Output looks as
      follows:
      
        [  347.007486] Unable to handle kernel paging request at virtual address fffb850e96492510
        [...]
        [  347.043065] [fffb850e96492510] address between user and kernel address ranges
        [  347.050205] Internal error: Oops: 96000004 [#1] SMP
        [...]
        [  347.190829] x13: 0000000000000000 x12: 0000000000000000
        [  347.196128] x11: fffc047ebe782800 x10: ffff808fd7d0fd10
        [  347.201427] x9 : 0000000000000000 x8 : 0000000000000000
        [  347.206726] x7 : 0000000000000000 x6 : 001c991738000000
        [  347.212025] x5 : 0000000000000018 x4 : 000000000000ba5a
        [  347.217325] x3 : 00000000000329c4 x2 : ffff808fd7cf0500
        [  347.222625] x1 : ffff808fd7d0fc00 x0 : ffff808fd7cf0500
        [  347.227926] Process test_verifier (pid: 4548, stack limit = 0x000000007467fa61)
        [  347.235221] Call trace:
        [  347.237656]  0xffff000002f3a4fc
        [  347.240784]  bpf_test_run+0x78/0xf8
        [  347.244260]  bpf_prog_test_run_skb+0x148/0x230
        [  347.248694]  SyS_bpf+0x77c/0x1110
        [  347.251999]  el0_svc_naked+0x30/0x34
        [  347.255564] Code: 9100075a d280220a 8b0a002a d37df04b (f86b694b)
        [...]
      
      In this case the index used in BPF r3 is the same as in r1
      at the time of the call, meaning we fed a pointer as index;
      here, it had the value 0xffff808fd7cf0500 which sits in x2.
      
      While I found tail calls to be working in general (also for
      hitting the error cases), I noticed the following in the code
      emission:
      
        # bpftool p d j i 988
        [...]
        38:   ldr     w10, [x1,x10]
        3c:   cmp     w2, w10
        40:   b.ge    0x000000000000007c              <-- signed cmp
        44:   mov     x10, #0x20                      // #32
        48:   cmp     x26, x10
        4c:   b.gt    0x000000000000007c
        50:   add     x26, x26, #0x1
        54:   mov     x10, #0x110                     // #272
        58:   add     x10, x1, x10
        5c:   lsl     x11, x2, #3
        60:   ldr     x11, [x10,x11]                  <-- faulting insn (f86b694b)
        64:   cbz     x11, 0x000000000000007c
        [...]
      
      Meaning, the tests passed because commit ddb55992 ("arm64:
      bpf: implement bpf_tail_call() helper") was using signed compares
      instead of unsigned which as a result had the test wrongly passing.
      
      Change this but also the tail call count test both into unsigned
      and cap the index as u32. Latter we did as well in 90caccdd
      ("bpf: fix bpf_tail_call() x64 JIT") and is needed in addition here,
      too. Tested on HiSilicon Hi1616.
      
      Result after patch:
      
        # bpftool p d j i 268
        [...]
        38:	ldr	w10, [x1,x10]
        3c:	add	w2, w2, #0x0
        40:	cmp	w2, w10
        44:	b.cs	0x0000000000000080
        48:	mov	x10, #0x20                  	// #32
        4c:	cmp	x26, x10
        50:	b.hi	0x0000000000000080
        54:	add	x26, x26, #0x1
        58:	mov	x10, #0x110                 	// #272
        5c:	add	x10, x1, x10
        60:	lsl	x11, x2, #3
        64:	ldr	x11, [x10,x11]
        68:	cbz	x11, 0x0000000000000080
        [...]
      
      Fixes: ddb55992 ("arm64: bpf: implement bpf_tail_call() helper")
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      16338a9b
  20. 15 2月, 2018 3 次提交
  21. 01 2月, 2018 1 次提交
    • D
      bpf: fix null pointer deref in bpf_prog_test_run_xdp · 65073a67
      Daniel Borkmann 提交于
      syzkaller was able to generate the following XDP program ...
      
        (18) r0 = 0x0
        (61) r5 = *(u32 *)(r1 +12)
        (04) (u32) r0 += (u32) 0
        (95) exit
      
      ... and trigger a NULL pointer dereference in ___bpf_prog_run()
      via bpf_prog_test_run_xdp() where this was attempted to run.
      
      Reason is that recent xdp_rxq_info addition to XDP programs
      updated all drivers, but not bpf_prog_test_run_xdp(), where
      xdp_buff is set up. Thus when context rewriter does the deref
      on the netdev it's NULL at runtime. Fix it by using xdp_rxq
      from loopback dev. __netif_get_rx_queue() helper can also be
      reused in various other locations later on.
      
      Fixes: 02dd3291 ("bpf: finally expose xdp_rxq_info to XDP bpf-programs")
      Reported-by: syzbot+1eb094057b338eb1fc00@syzkaller.appspotmail.com
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Cc: Jesper Dangaard Brouer <brouer@redhat.com>
      Acked-by: NJesper Dangaard Brouer <brouer@redhat.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      65073a67
  22. 27 1月, 2018 1 次提交
  23. 24 1月, 2018 1 次提交
    • Y
      tools/bpf: fix a test failure in selftests prog test_verifier · 35136920
      Yonghong Song 提交于
      Commit 111e6b45 ("selftests/bpf: make test_verifier run most programs")
      enables tools/testing/selftests/bpf/test_verifier unit cases to run
      via bpf_prog_test_run command. With the latest code base,
      test_verifier had one test case failure:
      
        ...
        #473/p check deducing bounds from const, 2 FAIL retval 1 != 0
        0: (b7) r0 = 1
        1: (75) if r0 s>= 0x1 goto pc+1
         R0=inv1 R1=ctx(id=0,off=0,imm=0) R10=fp0,call_-1
        2: (95) exit
      
        from 1 to 3: R0=inv1 R1=ctx(id=0,off=0,imm=0) R10=fp0,call_-1
        3: (d5) if r0 s<= 0x1 goto pc+1
         R0=inv1 R1=ctx(id=0,off=0,imm=0) R10=fp0,call_-1
        4: (95) exit
      
        from 3 to 5: R0=inv1 R1=ctx(id=0,off=0,imm=0) R10=fp0,call_-1
        5: (1f) r1 -= r0
        6: (95) exit
        processed 7 insns (limit 131072), stack depth 0
        ...
      
      The test case does not set return value in the test
      structure and hence the return value from the prog run
      is assumed to be 0. However, the actual return value is 1.
      As a result, the test failed. The fix is to correctly set
      the return value in the test structure.
      
      Fixes: 111e6b45 ("selftests/bpf: make test_verifier run most programs")
      Signed-off-by: NYonghong Song <yhs@fb.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      35136920
  24. 20 1月, 2018 1 次提交
  25. 19 1月, 2018 1 次提交
  26. 18 1月, 2018 1 次提交
    • D
      bpf: mark dst unknown on inconsistent {s, u}bounds adjustments · 6f16101e
      Daniel Borkmann 提交于
      syzkaller generated a BPF proglet and triggered a warning with
      the following:
      
        0: (b7) r0 = 0
        1: (d5) if r0 s<= 0x0 goto pc+0
         R0=inv0 R1=ctx(id=0,off=0,imm=0) R10=fp0
        2: (1f) r0 -= r1
         R0=inv0 R1=ctx(id=0,off=0,imm=0) R10=fp0
        verifier internal error: known but bad sbounds
      
      What happens is that in the first insn, r0's min/max value
      are both 0 due to the immediate assignment, later in the jsle
      test the bounds are updated for the min value in the false
      path, meaning, they yield smin_val = 1, smax_val = 0, and when
      ctx pointer is subtracted from r0, verifier bails out with the
      internal error and throwing a WARN since smin_val != smax_val
      for the known constant.
      
      For min_val > max_val scenario it means that reg_set_min_max()
      and reg_set_min_max_inv() (which both refine existing bounds)
      demonstrated that such branch cannot be taken at runtime.
      
      In above scenario for the case where it will be taken, the
      existing [0, 0] bounds are kept intact. Meaning, the rejection
      is not due to a verifier internal error, and therefore the
      WARN() is not necessary either.
      
      We could just reject such cases in adjust_{ptr,scalar}_min_max_vals()
      when either known scalars have smin_val != smax_val or
      umin_val != umax_val or any scalar reg with bounds
      smin_val > smax_val or umin_val > umax_val. However, there
      may be a small risk of breakage of buggy programs, so handle
      this more gracefully and in adjust_{ptr,scalar}_min_max_vals()
      just taint the dst reg as unknown scalar when we see ops with
      such kind of src reg.
      
      Reported-by: syzbot+6d362cadd45dc0a12ba4@syzkaller.appspotmail.com
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      6f16101e
  27. 17 1月, 2018 1 次提交
  28. 11 1月, 2018 1 次提交
    • D
      bpf: arsh is not supported in 32 bit alu thus reject it · 7891a87e
      Daniel Borkmann 提交于
      The following snippet was throwing an 'unknown opcode cc' warning
      in BPF interpreter:
      
        0: (18) r0 = 0x0
        2: (7b) *(u64 *)(r10 -16) = r0
        3: (cc) (u32) r0 s>>= (u32) r0
        4: (95) exit
      
      Although a number of JITs do support BPF_ALU | BPF_ARSH | BPF_{K,X}
      generation, not all of them do and interpreter does neither. We can
      leave existing ones and implement it later in bpf-next for the
      remaining ones, but reject this properly in verifier for the time
      being.
      
      Fixes: 17a52670 ("bpf: verifier (add verifier core)")
      Reported-by: syzbot+93c4904c5c70348a6890@syzkaller.appspotmail.com
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      7891a87e
  29. 28 12月, 2017 3 次提交
    • A
      bpf: fix max call depth check · aada9ce6
      Alexei Starovoitov 提交于
      fix off by one error in max call depth check
      and add a test
      
      Fixes: f4d7e40a ("bpf: introduce function calls (verification)")
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      aada9ce6
    • A
      selftests/bpf: additional stack depth tests · 6b86c421
      Alexei Starovoitov 提交于
      to test inner logic of stack depth tracking
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      6b86c421
    • J
      bpf: selftest for late caller stack size increase · 6b80ad29
      Jann Horn 提交于
      This checks that it is not possible to bypass the total stack size check in
      update_stack_depth() by calling a function that uses a large amount of
      stack memory *before* using a large amount of stack memory in the caller.
      
      Currently, the first added testcase causes a rejection as expected, but
      the second testcase is (AFAICS incorrectly) accepted:
      
      [...]
      #483/p calls: stack overflow using two frames (post-call access) FAIL
      Unexpected success to load!
      0: (85) call pc+2
      caller:
       R10=fp0,call_-1
      callee:
       frame1: R1=ctx(id=0,off=0,imm=0) R10=fp0,call_0
      3: (72) *(u8 *)(r10 -300) = 0
      4: (b7) r0 = 0
      5: (95) exit
      returning from callee:
       frame1: R0_w=inv0 R1=ctx(id=0,off=0,imm=0) R10=fp0,call_0
      to caller at 1:
       R0_w=inv0 R10=fp0,call_-1
      
      from 5 to 1: R0=inv0 R10=fp0,call_-1
      1: (72) *(u8 *)(r10 -300) = 0
      2: (95) exit
      processed 6 insns, stack depth 300+300
      [...]
      Summary: 704 PASSED, 1 FAILED
      
      AFAICS the JIT-generated code for the second testcase shows that this
      really causes the stack pointer to be decremented by 300+300:
      
      first function:
      00000000  55                push rbp
      00000001  4889E5            mov rbp,rsp
      00000004  4881EC58010000    sub rsp,0x158
      0000000B  4883ED28          sub rbp,byte +0x28
      [...]
      00000025  E89AB3AFE5        call 0xffffffffe5afb3c4
      0000002A  C685D4FEFFFF00    mov byte [rbp-0x12c],0x0
      [...]
      00000041  4883C528          add rbp,byte +0x28
      00000045  C9                leave
      00000046  C3                ret
      
      second function:
      00000000  55                push rbp
      00000001  4889E5            mov rbp,rsp
      00000004  4881EC58010000    sub rsp,0x158
      0000000B  4883ED28          sub rbp,byte +0x28
      [...]
      00000025  C685D4FEFFFF00    mov byte [rbp-0x12c],0x0
      [...]
      0000003E  4883C528          add rbp,byte +0x28
      00000042  C9                leave
      00000043  C3                ret
      Signed-off-by: NJann Horn <jannh@google.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      6b80ad29
  30. 24 12月, 2017 1 次提交
    • G
      bpf: fix stacksafe exploration when comparing states · fd05e57b
      Gianluca Borello 提交于
      Commit cc2b14d5 ("bpf: teach verifier to recognize zero initialized
      stack") introduced a very relaxed check when comparing stacks of different
      states, effectively returning a positive result in many cases where it
      shouldn't.
      
      This can create problems in cases such as this following C pseudocode:
      
      long var;
      long *x = bpf_map_lookup(...);
      if (!x)
              return;
      
      if (*x != 0xbeef)
              var = 0;
      else
              var = 1;
      
      /* This is the key part, calling a helper causes an explored state
       * to be saved with the information that "var" is on the stack as
       * STACK_ZERO, since the helper is first met by the verifier after
       * the "var = 0" assignment. This state will however be wrongly used
       * also for the "var = 1" case, so the verifier assumes "var" is always
       * 0 and will replace the NULL assignment with nops, because the
       * search pruning prevents it from exploring the faulty branch.
       */
      bpf_ktime_get_ns();
      
      if (var)
              *(long *)0 = 0xbeef;
      
      Fix the issue by making sure that the stack is fully explored before
      returning a positive comparison result.
      
      Also attach a couple tests that highlight the bad behavior. In the first
      test, without this fix instructions 16 and 17 are replaced with nops
      instead of being rejected by the verifier.
      
      The second test, instead, allows a program to make a potentially illegal
      read from the stack.
      
      Fixes: cc2b14d5 ("bpf: teach verifier to recognize zero initialized stack")
      Signed-off-by: NGianluca Borello <g.borello@gmail.com>
      Acked-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      fd05e57b
  31. 21 12月, 2017 1 次提交
    • A
      bpf: do not allow root to mangle valid pointers · 82abbf8d
      Alexei Starovoitov 提交于
      Do not allow root to convert valid pointers into unknown scalars.
      In particular disallow:
       ptr &= reg
       ptr <<= reg
       ptr += ptr
      and explicitly allow:
       ptr -= ptr
      since pkt_end - pkt == length
      
      1.
      This minimizes amount of address leaks root can do.
      In the future may need to further tighten the leaks with kptr_restrict.
      
      2.
      If program has such pointer math it's likely a user mistake and
      when verifier complains about it right away instead of many instructions
      later on invalid memory access it's easier for users to fix their progs.
      
      3.
      when register holding a pointer cannot change to scalar it allows JITs to
      optimize better. Like 32-bit archs could use single register for pointers
      instead of a pair required to hold 64-bit scalars.
      
      4.
      reduces architecture dependent behavior. Since code:
      r1 = r10;
      r1 &= 0xff;
      if (r1 ...)
      will behave differently arm64 vs x64 and offloaded vs native.
      
      A significant chunk of ptr mangling was allowed by
      commit f1174f77 ("bpf/verifier: rework value tracking")
      yet some of it was allowed even earlier.
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      82abbf8d