)]}'
{
  "commit": "718a346ee1b847127bf441c795a12a5753dfb048",
  "tree": "1b175f3bd0db7943a781a70ceec98221df011a17",
  "parents": [
    "6ea22b4b233ca336c041fcaacbf5c397c0e70da6"
  ],
  "author": {
    "name": "Daniel Borkmann",
    "email": "daniel@iogearbox.net",
    "time": "Tue Apr 11 15:24:13 2023 +0000"
  },
  "committer": {
    "name": "Arnav Kansal",
    "email": "rnv@google.com",
    "time": "Mon Sep 25 17:32:46 2023 +0000"
  },
  "message": "bpf: Fix incorrect verifier pruning due to missing register precision taints\n\n[ Upstream commit 71b547f561247897a0a14f3082730156c0533fed ]\n\nJuan Jose et al reported an issue found via fuzzing where the verifier\u0027s\npruning logic prematurely marks a program path as safe.\n\nConsider the following program:\n\n   0: (b7) r6 \u003d 1024\n   1: (b7) r7 \u003d 0\n   2: (b7) r8 \u003d 0\n   3: (b7) r9 \u003d -2147483648\n   4: (97) r6 %\u003d 1025\n   5: (05) goto pc+0\n   6: (bd) if r6 \u003c\u003d r9 goto pc+2\n   7: (97) r6 %\u003d 1\n   8: (b7) r9 \u003d 0\n   9: (bd) if r6 \u003c\u003d r9 goto pc+1\n  10: (b7) r6 \u003d 0\n  11: (b7) r0 \u003d 0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  13: (18) r4 \u003d 0xffff888103693400 // map_ptr(ks\u003d4,vs\u003d48)\n  15: (bf) r1 \u003d r4\n  16: (bf) r2 \u003d r10\n  17: (07) r2 +\u003d -4\n  18: (85) call bpf_map_lookup_elem#1\n  19: (55) if r0 !\u003d 0x0 goto pc+1\n  20: (95) exit\n  21: (77) r6 \u003e\u003e\u003d 10\n  22: (27) r6 *\u003d 8192\n  23: (bf) r1 \u003d r0\n  24: (0f) r0 +\u003d r6\n  25: (79) r3 \u003d *(u64 *)(r0 +0)\n  26: (7b) *(u64 *)(r1 +0) \u003d r3\n  27: (95) exit\n\nThe verifier treats this as safe, leading to oob read/write access due\nto an incorrect verifier conclusion:\n\n  func#0 @0\n  0: R1\u003dctx(off\u003d0,imm\u003d0) R10\u003dfp0\n  0: (b7) r6 \u003d 1024                     ; R6_w\u003d1024\n  1: (b7) r7 \u003d 0                        ; R7_w\u003d0\n  2: (b7) r8 \u003d 0                        ; R8_w\u003d0\n  3: (b7) r9 \u003d -2147483648              ; R9_w\u003d-2147483648\n  4: (97) r6 %\u003d 1025                    ; R6_w\u003dscalar()\n  5: (05) goto pc+0\n  6: (bd) if r6 \u003c\u003d r9 goto pc+2         ; R6_w\u003dscalar(umin\u003d18446744071562067969,var_off\u003d(0xffffffff00000000; 0xffffffff)) R9_w\u003d-2147483648\n  7: (97) r6 %\u003d 1                       ; R6_w\u003dscalar()\n  8: (b7) r9 \u003d 0                        ; R9\u003d0\n  9: (bd) if r6 \u003c\u003d r9 goto pc+1         ; R6\u003dscalar(umin\u003d1) R9\u003d0\n  10: (b7) r6 \u003d 0                       ; R6_w\u003d0\n  11: (b7) r0 \u003d 0                       ; R0_w\u003d0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  last_idx 12 first_idx 9\n  regs\u003d1 stack\u003d0 before 11: (b7) r0 \u003d 0\n  13: R0_w\u003d0 R10\u003dfp0 fp-8\u003d0000????\n  13: (18) r4 \u003d 0xffff8ad3886c2a00      ; R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  15: (bf) r1 \u003d r4                      ; R1_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  16: (bf) r2 \u003d r10                     ; R2_w\u003dfp0 R10\u003dfp0\n  17: (07) r2 +\u003d -4                     ; R2_w\u003dfp-4\n  18: (85) call bpf_map_lookup_elem#1   ; R0\u003dmap_value_or_null(id\u003d1,off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  19: (55) if r0 !\u003d 0x0 goto pc+1       ; R0\u003d0\n  20: (95) exit\n\n  from 19 to 21: R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6\u003d0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0 fp-8\u003dmmmm????\n  21: (77) r6 \u003e\u003e\u003d 10                    ; R6_w\u003d0\n  22: (27) r6 *\u003d 8192                   ; R6_w\u003d0\n  23: (bf) r1 \u003d r0                      ; R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R1_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  24: (0f) r0 +\u003d r6\n  last_idx 24 first_idx 19\n  regs\u003d40 stack\u003d0 before 23: (bf) r1 \u003d r0\n  regs\u003d40 stack\u003d0 before 22: (27) r6 *\u003d 8192\n  regs\u003d40 stack\u003d0 before 21: (77) r6 \u003e\u003e\u003d 10\n  regs\u003d40 stack\u003d0 before 19: (55) if r0 !\u003d 0x0 goto pc+1\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R0_rw\u003dmap_value_or_null(id\u003d1,off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6_rw\u003dP0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0 fp-8\u003dmmmm????\n  last_idx 18 first_idx 9\n  regs\u003d40 stack\u003d0 before 18: (85) call bpf_map_lookup_elem#1\n  regs\u003d40 stack\u003d0 before 17: (07) r2 +\u003d -4\n  regs\u003d40 stack\u003d0 before 16: (bf) r2 \u003d r10\n  regs\u003d40 stack\u003d0 before 15: (bf) r1 \u003d r4\n  regs\u003d40 stack\u003d0 before 13: (18) r4 \u003d 0xffff8ad3886c2a00\n  regs\u003d40 stack\u003d0 before 12: (63) *(u32 *)(r10 -4) \u003d r0\n  regs\u003d40 stack\u003d0 before 11: (b7) r0 \u003d 0\n  regs\u003d40 stack\u003d0 before 10: (b7) r6 \u003d 0\n  25: (79) r3 \u003d *(u64 *)(r0 +0)         ; R0_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R3_w\u003dscalar()\n  26: (7b) *(u64 *)(r1 +0) \u003d r3         ; R1_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R3_w\u003dscalar()\n  27: (95) exit\n\n  from 9 to 11: R1\u003dctx(off\u003d0,imm\u003d0) R6\u003d0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0\n  11: (b7) r0 \u003d 0                       ; R0_w\u003d0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  last_idx 12 first_idx 11\n  regs\u003d1 stack\u003d0 before 11: (b7) r0 \u003d 0\n  13: R0_w\u003d0 R10\u003dfp0 fp-8\u003d0000????\n  13: (18) r4 \u003d 0xffff8ad3886c2a00      ; R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  15: (bf) r1 \u003d r4                      ; R1_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  16: (bf) r2 \u003d r10                     ; R2_w\u003dfp0 R10\u003dfp0\n  17: (07) r2 +\u003d -4                     ; R2_w\u003dfp-4\n  18: (85) call bpf_map_lookup_elem#1\n  frame 0: propagating r6\n  last_idx 19 first_idx 11\n  regs\u003d40 stack\u003d0 before 18: (85) call bpf_map_lookup_elem#1\n  regs\u003d40 stack\u003d0 before 17: (07) r2 +\u003d -4\n  regs\u003d40 stack\u003d0 before 16: (bf) r2 \u003d r10\n  regs\u003d40 stack\u003d0 before 15: (bf) r1 \u003d r4\n  regs\u003d40 stack\u003d0 before 13: (18) r4 \u003d 0xffff8ad3886c2a00\n  regs\u003d40 stack\u003d0 before 12: (63) *(u32 *)(r10 -4) \u003d r0\n  regs\u003d40 stack\u003d0 before 11: (b7) r0 \u003d 0\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R1\u003dctx(off\u003d0,imm\u003d0) R6_r\u003dP0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0\n  last_idx 9 first_idx 9\n  regs\u003d40 stack\u003d0 before 9: (bd) if r6 \u003c\u003d r9 goto pc+1\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R1\u003dctx(off\u003d0,imm\u003d0) R6_rw\u003dPscalar() R7_w\u003d0 R8_w\u003d0 R9_rw\u003d0 R10\u003dfp0\n  last_idx 8 first_idx 0\n  regs\u003d40 stack\u003d0 before 8: (b7) r9 \u003d 0\n  regs\u003d40 stack\u003d0 before 7: (97) r6 %\u003d 1\n  regs\u003d40 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d40 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d40 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d40 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n  19: safe\n  frame 0: propagating r6\n  last_idx 9 first_idx 0\n  regs\u003d40 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d40 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d40 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d40 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n\n  from 6 to 9: safe\n  verification time 110 usec\n  stack depth 4\n  processed 36 insns (limit 1000000) max_states_per_insn 0 total_states 3 peak_states 3 mark_read 2\n\nThe verifier considers this program as safe by mistakenly pruning unsafe\ncode paths. In the above func#0, code lines 0-10 are of interest. In line\n0-3 registers r6 to r9 are initialized with known scalar values. In line 4\nthe register r6 is reset to an unknown scalar given the verifier does not\ntrack modulo operations. Due to this, the verifier can also not determine\nprecisely which branches in line 6 and 9 are taken, therefore it needs to\nexplore them both.\n\nAs can be seen, the verifier starts with exploring the false/fall-through\npaths first. The \u0027from 19 to 21\u0027 path has both r6\u003d0 and r9\u003d0 and the pointer\narithmetic on r0 +\u003d r6 is therefore considered safe. Given the arithmetic,\nr6 is correctly marked for precision tracking where backtracking kicks in\nwhere it walks back the current path all the way where r6 was set to 0 in\nthe fall-through branch.\n\nNext, the pruning logics pops the path \u0027from 9 to 11\u0027 from the stack. Also\nhere, the state of the registers is the same, that is, r6\u003d0 and r9\u003d0, so\nthat at line 19 the path can be pruned as it is considered safe. It is\ninteresting to note that the conditional in line 9 turned r6 into a more\nprecise state, that is, in the fall-through path at the beginning of line\n10, it is R6\u003dscalar(umin\u003d1), and in the branch-taken path (which is analyzed\nhere) at the beginning of line 11, r6 turned into a known const r6\u003d0 as\nr9\u003d0 prior to that and therefore (unsigned) r6 \u003c\u003d 0 concludes that r6 must\nbe 0 (**):\n\n  [...]                                 ; R6_w\u003dscalar()\n  9: (bd) if r6 \u003c\u003d r9 goto pc+1         ; R6\u003dscalar(umin\u003d1) R9\u003d0\n  [...]\n\n  from 9 to 11: R1\u003dctx(off\u003d0,imm\u003d0) R6\u003d0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0\n  [...]\n\nThe next path is \u0027from 6 to 9\u0027. The verifier considers the old and current\nstate equivalent, and therefore prunes the search incorrectly. Looking into\nthe two states which are being compared by the pruning logic at line 9, the\nold state consists of R6_rwD\u003dPscalar() R9_rwD\u003d0 R10\u003dfp0 and the new state\nconsists of R1\u003dctx(off\u003d0,imm\u003d0) R6_w\u003dscalar(umax\u003d18446744071562067968)\nR7_w\u003d0 R8_w\u003d0 R9_w\u003d-2147483648 R10\u003dfp0. While r6 had the reg-\u003eprecise flag\ncorrectly set in the old state, r9 did not. Both r6\u0027es are considered as\nequivalent given the old one is a superset of the current, more precise one,\nhowever, r9\u0027s actual values (0 vs 0x80000000) mismatch. Given the old r9\ndid not have reg-\u003eprecise flag set, the verifier does not consider the\nregister as contributing to the precision state of r6, and therefore it\nconsidered both r9 states as equivalent. However, for this specific pruned\npath (which is also the actual path taken at runtime), register r6 will be\n0x400 and r9 0x80000000 when reaching line 21, thus oob-accessing the map.\n\nThe purpose of precision tracking is to initially mark registers (including\nspilled ones) as imprecise to help verifier\u0027s pruning logic finding equivalent\nstates it can then prune if they don\u0027t contribute to the program\u0027s safety\naspects. For example, if registers are used for pointer arithmetic or to pass\nconstant length to a helper, then the verifier sets reg-\u003eprecise flag and\nbacktracks the BPF program instruction sequence and chain of verifier states\nto ensure that the given register or stack slot including their dependencies\nare marked as precisely tracked scalar. This also includes any other registers\nand slots that contribute to a tracked state of given registers/stack slot.\nThis backtracking relies on recorded jmp_history and is able to traverse\nentire chain of parent states. This process ends only when all the necessary\nregisters/slots and their transitive dependencies are marked as precise.\n\nThe backtrack_insn() is called from the current instruction up to the first\ninstruction, and its purpose is to compute a bitmask of registers and stack\nslots that need precision tracking in the parent\u0027s verifier state. For example,\nif a current instruction is r6 \u003d r7, then r6 needs precision after this\ninstruction and r7 needs precision before this instruction, that is, in the\nparent state. Hence for the latter r7 is marked and r6 unmarked.\n\nFor the class of jmp/jmp32 instructions, backtrack_insn() today only looks\nat call and exit instructions and for all other conditionals the masks\nremain as-is. However, in the given situation register r6 has a dependency\non r9 (as described above in **), so also that one needs to be marked for\nprecision tracking. In other words, if an imprecise register influences a\nprecise one, then the imprecise register should also be marked precise.\nMeaning, in the parent state both dest and src register need to be tracked\nfor precision and therefore the marking must be more conservative by setting\nreg-\u003eprecise flag for both. The precision propagation needs to cover both\nfor the conditional: if the src reg was marked but not the dst reg and vice\nversa.\n\nAfter the fix the program is correctly rejected:\n\n  func#0 @0\n  0: R1\u003dctx(off\u003d0,imm\u003d0) R10\u003dfp0\n  0: (b7) r6 \u003d 1024                     ; R6_w\u003d1024\n  1: (b7) r7 \u003d 0                        ; R7_w\u003d0\n  2: (b7) r8 \u003d 0                        ; R8_w\u003d0\n  3: (b7) r9 \u003d -2147483648              ; R9_w\u003d-2147483648\n  4: (97) r6 %\u003d 1025                    ; R6_w\u003dscalar()\n  5: (05) goto pc+0\n  6: (bd) if r6 \u003c\u003d r9 goto pc+2         ; R6_w\u003dscalar(umin\u003d18446744071562067969,var_off\u003d(0xffffffff80000000; 0x7fffffff),u32_min\u003d-2147483648) R9_w\u003d-2147483648\n  7: (97) r6 %\u003d 1                       ; R6_w\u003dscalar()\n  8: (b7) r9 \u003d 0                        ; R9\u003d0\n  9: (bd) if r6 \u003c\u003d r9 goto pc+1         ; R6\u003dscalar(umin\u003d1) R9\u003d0\n  10: (b7) r6 \u003d 0                       ; R6_w\u003d0\n  11: (b7) r0 \u003d 0                       ; R0_w\u003d0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  last_idx 12 first_idx 9\n  regs\u003d1 stack\u003d0 before 11: (b7) r0 \u003d 0\n  13: R0_w\u003d0 R10\u003dfp0 fp-8\u003d0000????\n  13: (18) r4 \u003d 0xffff9290dc5bfe00      ; R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  15: (bf) r1 \u003d r4                      ; R1_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  16: (bf) r2 \u003d r10                     ; R2_w\u003dfp0 R10\u003dfp0\n  17: (07) r2 +\u003d -4                     ; R2_w\u003dfp-4\n  18: (85) call bpf_map_lookup_elem#1   ; R0\u003dmap_value_or_null(id\u003d1,off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  19: (55) if r0 !\u003d 0x0 goto pc+1       ; R0\u003d0\n  20: (95) exit\n\n  from 19 to 21: R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6\u003d0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0 fp-8\u003dmmmm????\n  21: (77) r6 \u003e\u003e\u003d 10                    ; R6_w\u003d0\n  22: (27) r6 *\u003d 8192                   ; R6_w\u003d0\n  23: (bf) r1 \u003d r0                      ; R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R1_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  24: (0f) r0 +\u003d r6\n  last_idx 24 first_idx 19\n  regs\u003d40 stack\u003d0 before 23: (bf) r1 \u003d r0\n  regs\u003d40 stack\u003d0 before 22: (27) r6 *\u003d 8192\n  regs\u003d40 stack\u003d0 before 21: (77) r6 \u003e\u003e\u003d 10\n  regs\u003d40 stack\u003d0 before 19: (55) if r0 !\u003d 0x0 goto pc+1\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R0_rw\u003dmap_value_or_null(id\u003d1,off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6_rw\u003dP0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0 fp-8\u003dmmmm????\n  last_idx 18 first_idx 9\n  regs\u003d40 stack\u003d0 before 18: (85) call bpf_map_lookup_elem#1\n  regs\u003d40 stack\u003d0 before 17: (07) r2 +\u003d -4\n  regs\u003d40 stack\u003d0 before 16: (bf) r2 \u003d r10\n  regs\u003d40 stack\u003d0 before 15: (bf) r1 \u003d r4\n  regs\u003d40 stack\u003d0 before 13: (18) r4 \u003d 0xffff9290dc5bfe00\n  regs\u003d40 stack\u003d0 before 12: (63) *(u32 *)(r10 -4) \u003d r0\n  regs\u003d40 stack\u003d0 before 11: (b7) r0 \u003d 0\n  regs\u003d40 stack\u003d0 before 10: (b7) r6 \u003d 0\n  25: (79) r3 \u003d *(u64 *)(r0 +0)         ; R0_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R3_w\u003dscalar()\n  26: (7b) *(u64 *)(r1 +0) \u003d r3         ; R1_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R3_w\u003dscalar()\n  27: (95) exit\n\n  from 9 to 11: R1\u003dctx(off\u003d0,imm\u003d0) R6\u003d0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0\n  11: (b7) r0 \u003d 0                       ; R0_w\u003d0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  last_idx 12 first_idx 11\n  regs\u003d1 stack\u003d0 before 11: (b7) r0 \u003d 0\n  13: R0_w\u003d0 R10\u003dfp0 fp-8\u003d0000????\n  13: (18) r4 \u003d 0xffff9290dc5bfe00      ; R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  15: (bf) r1 \u003d r4                      ; R1_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  16: (bf) r2 \u003d r10                     ; R2_w\u003dfp0 R10\u003dfp0\n  17: (07) r2 +\u003d -4                     ; R2_w\u003dfp-4\n  18: (85) call bpf_map_lookup_elem#1\n  frame 0: propagating r6\n  last_idx 19 first_idx 11\n  regs\u003d40 stack\u003d0 before 18: (85) call bpf_map_lookup_elem#1\n  regs\u003d40 stack\u003d0 before 17: (07) r2 +\u003d -4\n  regs\u003d40 stack\u003d0 before 16: (bf) r2 \u003d r10\n  regs\u003d40 stack\u003d0 before 15: (bf) r1 \u003d r4\n  regs\u003d40 stack\u003d0 before 13: (18) r4 \u003d 0xffff9290dc5bfe00\n  regs\u003d40 stack\u003d0 before 12: (63) *(u32 *)(r10 -4) \u003d r0\n  regs\u003d40 stack\u003d0 before 11: (b7) r0 \u003d 0\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R1\u003dctx(off\u003d0,imm\u003d0) R6_r\u003dP0 R7\u003d0 R8\u003d0 R9\u003d0 R10\u003dfp0\n  last_idx 9 first_idx 9\n  regs\u003d40 stack\u003d0 before 9: (bd) if r6 \u003c\u003d r9 goto pc+1\n  parent didn\u0027t have regs\u003d240 stack\u003d0 marks: R1\u003dctx(off\u003d0,imm\u003d0) R6_rw\u003dPscalar() R7_w\u003d0 R8_w\u003d0 R9_rw\u003dP0 R10\u003dfp0\n  last_idx 8 first_idx 0\n  regs\u003d240 stack\u003d0 before 8: (b7) r9 \u003d 0\n  regs\u003d40 stack\u003d0 before 7: (97) r6 %\u003d 1\n  regs\u003d40 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d240 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d240 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d240 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n  19: safe\n\n  from 6 to 9: R1\u003dctx(off\u003d0,imm\u003d0) R6_w\u003dscalar(umax\u003d18446744071562067968) R7_w\u003d0 R8_w\u003d0 R9_w\u003d-2147483648 R10\u003dfp0\n  9: (bd) if r6 \u003c\u003d r9 goto pc+1\n  last_idx 9 first_idx 0\n  regs\u003d40 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d240 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d240 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d240 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n  last_idx 9 first_idx 0\n  regs\u003d200 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d240 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d240 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d240 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n  11: R6\u003dscalar(umax\u003d18446744071562067968) R9\u003d-2147483648\n  11: (b7) r0 \u003d 0                       ; R0_w\u003d0\n  12: (63) *(u32 *)(r10 -4) \u003d r0\n  last_idx 12 first_idx 11\n  regs\u003d1 stack\u003d0 before 11: (b7) r0 \u003d 0\n  13: R0_w\u003d0 R10\u003dfp0 fp-8\u003d0000????\n  13: (18) r4 \u003d 0xffff9290dc5bfe00      ; R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  15: (bf) r1 \u003d r4                      ; R1_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R4_w\u003dmap_ptr(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  16: (bf) r2 \u003d r10                     ; R2_w\u003dfp0 R10\u003dfp0\n  17: (07) r2 +\u003d -4                     ; R2_w\u003dfp-4\n  18: (85) call bpf_map_lookup_elem#1   ; R0_w\u003dmap_value_or_null(id\u003d3,off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  19: (55) if r0 !\u003d 0x0 goto pc+1       ; R0_w\u003d0\n  20: (95) exit\n\n  from 19 to 21: R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6\u003dscalar(umax\u003d18446744071562067968) R7\u003d0 R8\u003d0 R9\u003d-2147483648 R10\u003dfp0 fp-8\u003dmmmm????\n  21: (77) r6 \u003e\u003e\u003d 10                    ; R6_w\u003dscalar(umax\u003d18014398507384832,var_off\u003d(0x0; 0x3fffffffffffff))\n  22: (27) r6 *\u003d 8192                   ; R6_w\u003dscalar(smax\u003d9223372036854767616,umax\u003d18446744073709543424,var_off\u003d(0x0; 0xffffffffffffe000),s32_max\u003d2147475456,u32_max\u003d-8192)\n  23: (bf) r1 \u003d r0                      ; R0\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R1_w\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0)\n  24: (0f) r0 +\u003d r6\n  last_idx 24 first_idx 21\n  regs\u003d40 stack\u003d0 before 23: (bf) r1 \u003d r0\n  regs\u003d40 stack\u003d0 before 22: (27) r6 *\u003d 8192\n  regs\u003d40 stack\u003d0 before 21: (77) r6 \u003e\u003e\u003d 10\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R0_rw\u003dmap_value(off\u003d0,ks\u003d4,vs\u003d48,imm\u003d0) R6_r\u003dPscalar(umax\u003d18446744071562067968) R7\u003d0 R8\u003d0 R9\u003d-2147483648 R10\u003dfp0 fp-8\u003dmmmm????\n  last_idx 19 first_idx 11\n  regs\u003d40 stack\u003d0 before 19: (55) if r0 !\u003d 0x0 goto pc+1\n  regs\u003d40 stack\u003d0 before 18: (85) call bpf_map_lookup_elem#1\n  regs\u003d40 stack\u003d0 before 17: (07) r2 +\u003d -4\n  regs\u003d40 stack\u003d0 before 16: (bf) r2 \u003d r10\n  regs\u003d40 stack\u003d0 before 15: (bf) r1 \u003d r4\n  regs\u003d40 stack\u003d0 before 13: (18) r4 \u003d 0xffff9290dc5bfe00\n  regs\u003d40 stack\u003d0 before 12: (63) *(u32 *)(r10 -4) \u003d r0\n  regs\u003d40 stack\u003d0 before 11: (b7) r0 \u003d 0\n  parent didn\u0027t have regs\u003d40 stack\u003d0 marks: R1\u003dctx(off\u003d0,imm\u003d0) R6_rw\u003dPscalar(umax\u003d18446744071562067968) R7_w\u003d0 R8_w\u003d0 R9_w\u003d-2147483648 R10\u003dfp0\n  last_idx 9 first_idx 0\n  regs\u003d40 stack\u003d0 before 9: (bd) if r6 \u003c\u003d r9 goto pc+1\n  regs\u003d240 stack\u003d0 before 6: (bd) if r6 \u003c\u003d r9 goto pc+2\n  regs\u003d240 stack\u003d0 before 5: (05) goto pc+0\n  regs\u003d240 stack\u003d0 before 4: (97) r6 %\u003d 1025\n  regs\u003d240 stack\u003d0 before 3: (b7) r9 \u003d -2147483648\n  regs\u003d40 stack\u003d0 before 2: (b7) r8 \u003d 0\n  regs\u003d40 stack\u003d0 before 1: (b7) r7 \u003d 0\n  regs\u003d40 stack\u003d0 before 0: (b7) r6 \u003d 1024\n  math between map_value pointer and register with unbounded min value is not allowed\n  verification time 886 usec\n  stack depth 4\n  processed 49 insns (limit 1000000) max_states_per_insn 1 total_states 5 peak_states 5 mark_read 2\n\nBUG\u003db/301580706\nTEST\u003dpresubmit\nRELEASE_NOTE\u003dFixes CVE-2023-2163 in the Linux Kernel.\n\ncos-patch: security-high\nFixes: b5dc0163d8fd (\"bpf: precise scalar_value tracking\")\nReported-by: Juan Jose Lopez Jaimez \u003cjjlopezjaimez@google.com\u003e\nReported-by: Meador Inge \u003cmeadori@google.com\u003e\nReported-by: Simon Scannell \u003csimonscannell@google.com\u003e\nReported-by: Nenad Stojanovski \u003cthenenadx@google.com\u003e\nChange-Id: Ide0a29fbba29718a7694d2fb838ae562b68cb9ed\nSigned-off-by: Daniel Borkmann \u003cdaniel@iogearbox.net\u003e\nCo-developed-by: Andrii Nakryiko \u003candrii@kernel.org\u003e\nSigned-off-by: Andrii Nakryiko \u003candrii@kernel.org\u003e\nReviewed-by: John Fastabend \u003cjohn.fastabend@gmail.com\u003e\nReviewed-by: Juan Jose Lopez Jaimez \u003cjjlopezjaimez@google.com\u003e\nReviewed-by: Meador Inge \u003cmeadori@google.com\u003e\nReviewed-by: Simon Scannell \u003csimonscannell@google.com\u003e\nSigned-off-by: Sasha Levin \u003csashal@kernel.org\u003e\nReviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/57767\nTested-by: Cusky Presubmit Bot \u003cpresubmit@cos-infra-prod.iam.gserviceaccount.com\u003e\nReviewed-by: Oleksandr Tymoshenko \u003covt@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "674ecdfc32d851f06e402535e1d3ca34eb540a0b",
      "old_mode": 33188,
      "old_path": "kernel/bpf/verifier.c",
      "new_id": "9eb63987cf312e2db49e98de673881ae045e136b",
      "new_mode": 33188,
      "new_path": "kernel/bpf/verifier.c"
    }
  ]
}
