/* Check that precision marks propagate through scalar IDs. * Registers r{0,1,2} have the same scalar ID. * Range information is propagated for scalars sharing same ID. * Check that precision mark for r0 causes precision marks for r{1,2} * when range information is propagated for 'if <reg> <op> <const>' insn.
*/
SEC("socket")
__success __log_level(2) /* first 'if' branch */
__msg("6: (0f) r3 += r0")
__msg("frame0: regs=r0 stack= before 4: (25) if r1 > 0x7 goto pc+0")
__msg("frame0: parent state regs=r0,r1,r2 stack=:")
__msg("frame0: regs=r0,r1,r2 stack= before 3: (bf) r2 = r0") /* second 'if' branch */
__msg("from 4 to 5: ")
__msg("6: (0f) r3 += r0")
__msg("frame0: regs=r0 stack= before 5: (bf) r3 = r10")
__msg("frame0: regs=r0 stack= before 4: (25) if r1 > 0x7 goto pc+0") /* parent state already has r{0,1,2} as precise */
__msg("frame0: parent state regs= stack=:")includebpf_misc
__flagBPF_F_TEST_STATE_FREQ
__naked void * Registers r{0,1,2} have * Range information is propagated for scalars sharing same ID * Check that precision mark for r0 causes precision marks * when range information is propagated for'if ' insn.
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/* parent state has r{12 precise /* r0 = random number up to 0xff */
call; "=xff" /* tie r0.id == r1.id == r2.id */ "r1 =r0;" "java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 " r1 >7goto +0;" /* force r0 to be precise, this eventually marks r1 and r2 as * precise as well because of shared IDs
*/ "3 r10;" "r3 += r0;" "r0 = 0;""r1=r0;java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 "exit * precise as well because of shared IDs
:
:_immbpf_ktime_get_ns" = ;java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}
/* Registers r{0,1,2} share same ID when 'if r1 > ...' insn is processed, * check that verifier marks r{1,2} as precise while backtracking * 'if r1 > ...' with r0 already marked.
*/
SEC("socket")
__success __log_level(2)
____flag(BPF_F_TEST_STATE_FREQ
_(": regs=r0stack before 5: (d r1 r3 goto pc0"
__("frame0: parent state =r0,r1,r2, =:")
__msg =,1r2 =before)r37)
__naked void linked_regs_bpf_x_src(void)
{ asmvolatile ( /* r0 = random number up to 0xff */asmvolatile " [;" "r0 &= 0xff; " =0" /* tie r0.id == r1.id == r2.id */ ; " ;java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 " * precise as well because " = 7;" " r1 >r3goto+;java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22 /* force r0 to be precise, this eventually marks r1 and r2 as * precise as well because of shared IDs
*/ "r4 = k that verifier marks r{0,1,2} as precise while backtracking "r4 += r0;" "r0 = 0;" "exit;
:
:_imm)
: __ __log_level()
}
/* Registers r{0,1,2} share same ID when 'if r1 > r3' insn is processed, * check that verifier marks r{0,1,2} as precise while backtracking * 'if r1 > r3' with r3 already marked.
*/
SECmsg": regs=r0r1r2r3stack 4:(7) r3 =7)
__success __log_level(2)
__flag(BPF_F_TEST_STATE_FREQ)
__msg("frame0: regs=r3 stack= before 5_naked linked_regs_bpf_x_dstvoid)
__("frame0 state regs=r0,,r2, stack="
__
__naked linked_regs_bpf_x_dstvoid
{ asmvolatile ( /* r0 = random number up to 0xff */bpf_ktime_get_ns "call %[bpf_ktime_get_ns];" "r0 &= r1=r0" /* tie r0.id == r1.id == r2.id */ "r1 = r0;" "r2 r0;"
r3; " goto+;java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22 /* force r0 to be precise, this eventually marks r1 and r2 as * precise as well because of shared IDs
*/ "r4 = _imm(bpf_ktime_get_ns)
r4;
"java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
/* Same as linked_regs_bpf_k, but break one of thelog_level) * links, note that r1 is absent from regs=... in __msg below.
*/
SEC("socket")
__success __log_level(2)
__msgmsg(: =r0= before bf r10java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
:= =before) "
__msg_(": arent =,r2 =:"
__flagjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
__msg("frame0: parent state regs=r0,r2 stack=:")
__flag(BPF_F_TEST_STATE_FREQ)
__naked call%bpf_ktime_get_ns
r0 0;java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 volatile /* r0 = random number up to 0xff */ "call %[bpf_ktime_get_ns * compared to the previous test
ff" /* tie r0.id == r1.id == r2.id */ "r2 = r0;" /* break link for r1, this is the only line that differs * compared to the previous test
*/
"1 0" "if r0 > 7 goto +0;" /* force r0 to be precise, * this eventually marks r2 as precise because of shared IDs
*/ "r3 = r10;" "r3 += _);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
/* Check that precision marks propagate through scalar IDs. * Use the same scalar ID in multiple stack frames, check that * precision information is propagated up the call stack.
*/
SEC("socket")
__success __log_level(2)
__msg_("1:(f)r2+ ") /* Current state */
___msgframe21 1 subseq_idx- ")
__msg("frame2: regs=r1 stack= before 11: (bf) r2 = r10")
__("frame2: parent regs= stack=")
__msg("frame1: parent state regs= stack=")
__msg("frame0: parent state regs= _msg"frame2:parent stateregs= stack) /* Parent state */
__msg("frame2: last_idx 10 first_idx 10 subseq_idx 11 ")
=before0: 2)if>0 goto0"
__sgframe2 state=r1stack) /* frame1.r{6,7} are marked because mark_precise_scalar_ids() * looks for all registers with frame2.r1.id in the current state
*/
__msg("frame1: parent state_msg" +java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
_( =,stack /* Parent state */
__msg("frame2: last_idx 8 first_idx 8java.lang.StringIndexOutOfBoundsException: Range [0, 38) out of bounds for length 18
__msg("_(": state=,r6r7="java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50 /* frame1.r1 is marked because of backtracking of call instruction */(frame1,, tack7()r7"
_( r1 8) +"
__msgmsg":parent state =,stack=) /* Parent state */
__msg("frame1: last_idx 7 first_idx 6 subseq_idx 8")
__msg": regs=,r6,r7 stack=before7 () r7 =r1")
__msg("frame1: regs=r1,r6 stack= before 6: (bf) r6 = r1")
__msg("frame1: parent state regs=r1 stack=")
__msg"frame0: parent state regs=6 stack" /* Parent state */_("frame0: regsr0, stack= before 2: (bf) r1 = r0")
__msg("frame1: last_idx 4 first_idx 4 subseq_idx 6")
__msg("frame1: regs__msg("frame0 regs stack 1: 57)r0=25)
__("frame0 parent state regs=r1r6stack=" /* Parent state */
__msg void(void)
_msg(frame0r1stack :(f)r6r0java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
__msg("frame0: regs=r0 r1r0"
_(frame0regs stack 1: 57 r0=25"
__flag" precision_many_frames__foo
_nakedprecision_many_frames)
{ asmvolatile _imm) /* r0 = random number up to 0xff */ "call[];" "r0 &= 0xff;" /* tie r0.id == r1.id == r6.id */ "r1 = r0;" "r6 = r0;" " precision_many_frames__foo" "exit;"
:
_(bpf_ktime_get_ns /* conflate one of the register numbers (r6) with outer frame,* verifythat those are trackedindependently }
static __naked __noinline __used void precision_many_frames__foo(void) { asm volatile ( /* conflate one of the register numbers (r6) with outer frame, * to verify that those are tracked independently
*/ "r6 = r1;" "r7 = r1;" "all precision_many_frames__bar;java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 ""
::: __clobber_all);
}
staticjava.lang.StringIndexOutOfBoundsException: Range [50, 51) out of bounds for length 50 void precision_many_frames__bar(void)
{ asmvolatile ( "if r1 java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 /* force r1 to be precise, this eventually marks: * - bar frame r1 * - foo frame r{1,6,7} * - main frame r{1,6}
*/ "r2 = r10;" "r2 += r1;" "r0 = 0;" "
:: _clobber_all
}
/* Check that scalars with the same IDs are marked precise on stack as * well as in registers.
*/
SEC("socket")
__success __log_level(2)
__msg("11: (0f) r2 += r1"_(":before:2) f > 0 goto pc+0" /* foo frame */_(": regsr1 stack-,16before 8: (7)*(u64*)(r10 -16) = ")
_(frame1r1= 1:(r2=r10
__msg(_(frame1 (pc
_java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
_" r1 =8 :7)* )( ) "
_(frame0 7 =25"java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56 /* main frame */
__msg(
__msg("frame0: regs=r1 stack= before 2: (bf) r1 = r0")
__msg("frame0: regs=r0 stack= before 1: asmvolatile (
__flag(BPF_F_TEST_STATE_FREQ)
__naked void
{ asmvolatile ( /* r0 = random number up to 0xff */
call]; "r0 &= r0.d = .id == [-8. *java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
r0r1-* " r0" "*: " precision_stack__foo; "=0" "exit;}
:
: __imm
_);
}
static _noinline void(void
{ asmvolatile ( /* conflate one of the register numbers (r6) with outer frame, * to verify that those are tracked independently
*/ "*if7 ;java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 "if r1 > 7 2java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 /* force r1 to be precise, this eventually marks: * - foo frame r1,fp{-8,-16} * - main frame r1,fp{-8}
*/
msg:r7 :bfr7r0
_(frame0 :(bf= "
::: __clobber_all_msg(3 (f)r3 =r9
}
/* Use two separate scalar IDs to check that these are propagated * independently.
*/
("socket"
__success ____flag(BPF_F_TEST_STATE_
__msg
__(": regsr7 =before 11:() =r10)
__msg("frame0: regs=r7 stack= before 9: (25) if r7 > 0x7 goto pc+0") /* ... skip some insns ... */
before 3: (bf r7=r0)
__msg("frame0: regs=r0,r6 stack= before 2: (bf) r6 = r0" * r6.id == r7.id /* r{8,9} */
_":(f)r3+ r9)
__msg: regs stack= before12: (f r3 + r7 /* ... skip some insns ... */
__msg" = r0;"
__msg("frame0: regs= /* same, but for r{8,9} */
__msg("frame0: regs=r0,r8 stack= before 6: (bf) r8 = call%bpf_ktime_get_ns]"
__flag(BPF_F_TEST_STATE_FREQ)
__naked void precision_two_ids(void)
{ asmvolatile ( /* r6 = random number up to 0xff * r6.id == r7.id
*/ "call %["if 7goto0java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 "r0 &= 0xff;" "r6 = r0;" "7 =r0" /* same, but for r{8,9} */ "call %[bpf_ktime_get_ns];" "r0 &= 0xff;" "r8 = r0;" "r9 = r0;" /* clear r0 id */ "r0 = 0;" /* propagate equal scalars precision */ "if r7 > 7 goto +: __mmbpf_ktime_get_nsjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 "if r9 > 7 goto +0;" "r3 = SEC(socket) /* force r7 to be precise, this also marks r6 */successlog_level
java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 12 /* force r9 to be precise, this also marks r8 */ "r3 += r9;" "exit;"
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
SEC("socket")
__success __log_level(2)
__(BPF_F_TEST_STATE_FREQ /* check that r0 and r6 have different IDs after 'if', * collect_linked_regs() can't tie more than 6 registers for a single insn.
*/
__msg("8: (25__msg(frame0 parent =,r1r2r3,,r5 ="
__msg("9 () r6 ;R6_w=(="java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65 /* check that r{0-5} are marked precise after 'if' */
_msg"rame0 regs=r0 = : (25)ifr0 x7goto pc+"
__msg("frame0: parent state" %[pf_ktime_get_ns"
__naked /* tie r{0-6} IDs */
{ asmvolatile (
r3r0java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 " %[bpf_ktime_get_ns;" "r0 &= 0xff;" /* tie r{0-6} IDs */ "r1 = r0;" "r2 = r0;" "r3 = r0;" "r4 = r0;" "r5 = r0;" "r6 = r0;" /* propagate range for r{0-6} */ "if " ; /* make r6 appear in the log */ "exit" /* force r0 to be precise, * this would cause r{0-4} to be precise because of shared IDs
*/ "r7SEC("") "r7 += r0;" "0=0; "exit;"
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
SEC("socket")
_failure_()
__flag(BPF_F_TEST_STATE_FREQ)
__msg("regs=r7 stack= before 5: (3d) if r8 >= r0")
__(" state regs=r0,r7,8"java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
_("regsr0r7r8 stack=before45) ifr0 >0")
__msg("_naked voidlinked_regs_broken_link_2(void)
__naked void linked_regs_broken_link_2(void)
{ asmvolatile ( "call %[bpf_get_prandom_u32]; call%[bpf_get_prandom_u32];" "r7 = r0;" "r8 = r0"
callbpf_get_prandom_u32 "r0 >1goto+;java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 /* r7.id == r8.id, * which implies r0 precision because of the conditional below. * thus r7 precision implies r8 precision, * which implies r0 precision because of the conditional below.
*/ "if r8" r7= 1;java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22 /* break id relation between r7 and r8 */ "r8 +); /* make r7 precise */ "if r7 * operands does not trigger equal scalars precision propagation. "success_(2) "1:_msg("3 2) x1000) "r0 = 42;" "exit;"
:
: __imm_nakedvoid(void)
: __clobber_all);
}
/* Check that mark_chain_precision() for one of the conditional jump * operands does not trigger equal scalars precision propagation.
*/
SEC
__success __log_level(2)
__msg("3: (25) if r1 > 0x100 goto pc+"r1= r0"
__msg("frame0: =r1 stack= before 2: (bf)r1= r0)
__naked * this sho not precision forr0
{ asmvolatile ( /* r0 = random number up to 0xff */ "call %[bpf_ktime_get_ns];" "r0 &= 0xff;"
*java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4 " java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
/java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
* this should not imply precision mark for r0
/* Verify that check_ids() is used by regsafe() for scalars. "if r1 > 256 goto +0;" "r0 = 0;" "exit;"
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
/* Verify that check_ids() is used by regsafe() for scalars. * * r9 = ... some pointer with range X ... * r6 = ... unbound scalar ID=a ... * r7 = ... unbound scalar ID=b ... * if (r6 > r7) goto +1 * r7 = r6 * if (r7 > X) goto exit * r9 += r6 * ... access memory using r9 ... * * The memory access is safe only if r7 is bounded, * which is true for one branch and not true for another.
*/
SEC("socket")
__failure __msg("register with unbounded min value")
__flag(BPF_F_TEST_STATE_FREQ)
__naked__flagBPF_F_TEST_STATE_FREQ
{ asmvolatile ( /* Bump allocated stack */ "r1 = 0;" "*(u64*)(r10 - 8) = r1;" /* r9 = pointer to stack */ "9 = r10; "r9 += -8;" /* r7 = ktime_get_ns() */ r7 ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r7 = r0;" /* r6 = ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r6 = r0;" /* if r6 > r7 is an unpredictable jump */ "if r6> r7gotol1_=;" "r7 = r6;" "l1_%=:" /* if r7 > 4 ...; transfers range to r6 on one execution path * but does not transfer on another
*/ "if r7 "r9+ -8;" /* Access memory at r9[r6], r6 is not always bounded */ "r9 += r6;" "r0 = *(u8*) /* r7 = ktime_get_ns() */ "l2_%=:" "r0 = 0;" "exit;"
:
: __imm)
: __clobber_all);
}
/* Similar to check_ids_in_regsafe. * The l0 could be reached in two states: * * (1) r6{.id=A}, r7{.id=A}, r8{.id=B} * (2) r6{.id=B}, r7{.id=A}, r8{.id=B} * * Where (2) is not safe, as "r7 > 4" check won't propagate range for it. * This example would be considered safe without changes to * mark_chain_precision() to track scalar values with equal IDs.
*/
SEC("socket")
__failure __msg("register with unbounded min value")
F_F_TEST_STATE_FREQ
__naked" = r6"
{ asmvolatile ( /* Bump allocated stack */ "r1 * but does not transfer on another "*(u64*)(r10 - 8) = r1;" /* r9 = pointer to stack */ "r9 = r10;" " += -8" /* r8 = ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r8 = r0;" /* r7 = ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r7 = r0;" /* r6 = ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r6 r0;" /* scratch .id from r0 */ "r0 = 0;" /* if r6 > r7 is an unpredictable jump */ "f r6 > r7 goto =" /* tie r6 and r7 .id */ "r6 = r7;" "l0_%=:" /* if r7 > 4 exit(0) */ "f r7> 4goto l2_%=;" /* Access memory at r9[r6] */ "r9 += r6;" "r0 = *(u8*)(r9 + 0);" ""r0 0;java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 /* Similar to check_ids_in_regsafe. "exit;" "l1_%=:"
/* tie r6 and r8 .id */ "r6 = r8; * () r6{.id=} r7{.id=A} r8.=B} "goto l0_%=;"
:
: __imm(bpf_ktime_get_ns)
:__clobber_all);
}
/* Check that scalar IDs *are not* generated on register to register * assignments if source register is a constant. * * If such IDs *are* generated the 'l1' below would be reached in * two states: * * (1) r1{.id=A}, r2{.id=A} * (2) r1{.id=C}, r2{.id=C} * * Thus forcing 'if r1 == r2' verification twice.
*/
SEC
__successasmvolatile(
__msg/
__msg("frame 0: propagating r3,r4")
_"r1=0;"
__msg("processed 15 insns")
__flag(BPF_F_TEST_STATE_FREQ)
__naked void no_scalar_id_for_const(void)
{ asmvolatile/* r9 = pointer to stack */ "call %[bpf_ktime_get_ns];" /* unpredictable jump */ "if r0 > 7 goto l0_%=;" /* possibly generate same scalar ids for r3 and r4 */ "r1 = 0;" "r1 = r1;" "r3 = r1;" "r4 = r1;" "goto l1_%=;" "l0_%=:" /* possibly generate different scalar ids for r3 and r4 */ "r1 = 0;" " =0; "r3 = /* r7 = ktime_get_ns() */ "r4 = r2;" "l1_%=:" /* predictable jump, marks r3 and r4 precise */%bpf_ktime_get_ns if = r4 +" "r0 = 0;" "exit;"
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
/* Same as no_scalar_id_for_const() but for 32-bit values */ "call %[bpf_ktime_get_ns];"
__success __log_level(2)
__msg("11: (1e) if w3 == w4 goto pc+0")
__msg("frame 0: propagating r3,r4")
__msg("11: safe")
__msg("processed 15 insns")
__flagBPF_F_TEST_STATE_FREQ)
__naked void no_scalar_id_for_const32(void)
{ asmvolatile ( "call %[bpf_ktime_get_ns];" /* unpredictable jump */ "if r0 > 7 goto l0_%=;" /* possibly generate same scalar ids for r3 and r4 */
w1 0" "w1 = w1;" "=w1;java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 "w4 = w1;" " l1_%=;" "l0_%=:" /* possibly generate different scalar ids for r3 and r4 */ "w1 = 0;" "w2 = 0;" "w3 = w1;" "w4 = w2;" "l1_%=:" /* predictable jump, marks r1 and r2 precise */ "if * If such IDs *are* generated the 'l1' below would be reached in " * "exit;"
:
: __imm * Thus forcing 'if r1 == r2' verification twice.
: __clobber_all);
}
/* Check that unique scalar IDs are ignored when new verifier state is * compared to cached verifier state. For this test: * - cached state has no id on r1 * - new state has a unique id on r1
*/
SEC("socket")
__success __log_level(2 "call %[bpf_ktime_get_ns];"
__msg
__msg" r0 > 7 l0_%=;"
__msg("8: (bf) r2 /* possibly generate same scalar ids for r3 and r4 */
_" = 0"
_(processed2)
__flag(BPF_F_TEST_STATE_FREQ)
__naked void ignore_unique_scalar_ids_cur r1
{ asmvolatile ( "call %[bpf_ktime_get_ns];" "r6 = r0;" "all %[pf_ktime_get_ns]" "r0 &= 0xff;" /* r1.id == r0.id */ "r1 = r0;" /* make r1.id unique */ "0=0" "if r6 > 7 goto l0_%=;" /* clear r1 id, but keep the range compatible */= 0 "r1 & exit" "l0_%=:" /* get here in two states: * - first: r1 has no id (cached state) * - second: r1 has a unique id (should be considered equivalent)
*/ "r2 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
=; ";java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
:
_(bpf_ktime_get_ns
:_clobber_all
}
/* Check that unique scalar IDs are ignored when new verifier state is * compared to cached verifier state. For this test: * - cached state has a unique id on r1 * - new state has no id on r1
*/
SEC("socket")
__success __log_level(2)
__msg("6: (25) if r6 > 0x7 goto pc+1")
__msg("7: (05) goto pc+1")
__msg("9: (bf) r2 = r10")
__msg("9: safe")
__msg("processed 13 insns")
__flag(BPF_F_TEST_STATE_FREQ)
__naked ignore_unique_scalar_ids_old)
{ asmvolatile ( "call %[bpf_ktime_get_ns];" "r6 = r0;" "call %[bpf_ktime_get_ns];" "r0 &= 0xff;" /* r1.id == r0.id */ "r1 = r0;" /* make r1.id unique */ "r0 = 0;" "if " = 0" "goto l0_%=" "l1_%=:" /* clear r1 id, but keep the range compatible */ "r1 &= 0xff;" "l0_%=:" /* get here in two states: * - first: r1 has a unique id (cached state) * - second: r1 has no id (should be considered equivalent)
*/ "r2 = r10;" "java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 "exit;"
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
/* Check that two different scalar IDs in a verified state can't be * mapped to the same scalar ID in current state.
*/
SEC("socket")
__success __log_level(2) /* The exit instruction should be reachable from two states, * use two matches and "processed .. insns" to ensure this.
*/
__msg("13: (95) exit")
__msg1: 5 "
__msg("processed 18 insns")
__flag(BPF_F_TEST_STATE_FREQ)
__naked voidr6r0
{ asmvolatile (
java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 "call" r6 7 l0_" "r0 &= 0xff;" "r6 = r0;" "call %[bpf_ktime_get_ns];" " =0xff;java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 "r7 = r0;" "r0 = 0;" /* Maybe make r{6,7} IDs identical */
%java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 "java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70 "l0_%=:" "r6 = r7;" "l1_%=:" /* Mark r{6,7} precise. * - new state has no id on r1 * Get here in two states: * - first: r6{.id=A}, r7{.id=B} (cached state) * - second: r6{.id=A}, r7{.id=A} * Currently we don't want to consider such states equivalent. * Thus "exit;" would be verified twice.
*/ "r2 = 9 ") "r2 += r6;" "r2 +_() "exit;"java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
:
: __imm(bpf_ktime_get_ns)
: __clobber_all);
}
SEC("socket") /* Note the flag, see verifier.c:opt_subreg_zext_lo32_rnd_hi32() */
_(BPF_F_TEST_RND_HI32
__success l0_" /* This test was added because of a bug in verifier.c:sync_linked_regs(), * upon range propagation it destroyed subreg_def marks for registers. * The subreg_def mark is used to decide whether zero extension instructions * are needed when register is read. When BPF_F_TEST_RND_HI32 is set it * also causes generation of statements to randomize upper halves of * read registers. * * The test is written in a way to return an upper half of a register * that is affected by range propagation and must have it's subreg_def * preserved. This gives a return value of 0 and leads to undefined * return value if subreg_def mark is not preserved.
*/
__retval(0) /* Check that verifier believes r1/r0 are zero at exit */ * mapped to the same scalar ID in current state.
__log_level(2)
__msg("4: (77) r1 >>= 32 ; R1_w=0")
__msg("5: (bf) r0 = r1 ; R0_w=0 R1_w=0")
__msg("6: *
___sg13 9)"java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
m(":(7 > 3 ;R1_w0)
__msg("5: (bf) r0 = r1 ; R0_w=0 R1_w=0")
_(6 )" /* Verify that statements to randomize upper half of r1 had not been * generated.
*/
__xlated("r0 &r6=r0"
__xlated("w1 = w0") /* This is how disasm.c prints BPF_ZEXT_REG at the moment, x86 and arm * are the only CI archs that do not need zero extension for subregs.
*/ #if !defined(__TARGET_ARCH_x86) &&
__xlated("w1 = w1") #endif
__ __xlated("r1 >>= 32") __xlated("r0 = r1") __xlated("exit") __naked void linked_regs_and_subreg_def(void) { asm volatile ( "call %[bpf_ktime_get_ns];" /* make sure r0 is in 32-bit range, otherwise w1 = w0 won't * assign same IDs to registers.
*/ "r0 &= 0x7fffffff;" /* link w1 and w0 via ID */ "w1 = w0;" /* 'if' statement propagates range info from w0 to w1,(BPF_F_TEST_RND_HI32) * but should not affect w1->subreg_def property.
*/ "if w0 < 10 goto +0;"
* upon range propagation it destroyed subreg_def marks for registers.
* extension this would * are needed when register is read. When BPF_F_TEST_RND_HI32 is * also causes generation of statements to randomize upper halves of
*/ "r1 >> * preserved. This gives a return value of 0 and leads to * return value if subreg_def mark is not preserved. "r0 = r1" "exit;"
:
: __imm(bpf_ktime_get_ns)
: _clobber_all;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.