Commit 463ea64e authored by Menglong Dong's avatar Menglong Dong Committed by Alexei Starovoitov
Browse files

selftests/bpf: add testcase to verifier_bounds.c for BPF_JNE



Add testcase for the logic that the verifier tracks the BPF_JNE for regs.
The assembly function "reg_not_equal_const()" and "reg_equal_const" that
we add is exactly converted from the following case:

  u32 a = bpf_get_prandom_u32();
  u64 b = 0;

  a %= 8;
  /* the "a > 0" here will be optimized to "a != 0" */
  if (a > 0) {
    /* now the range of a should be [1, 7] */
    bpf_skb_store_bytes(skb, 0, &b, a, 0);
  }

Signed-off-by: default avatarMenglong Dong <menglong8.dong@gmail.com>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231219134800.1550388-5-menglong8.dong@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 31d9cc96
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -1075,4 +1075,66 @@ l0_%=: r0 = 0; \
	: __clobber_all);
}

SEC("tc")
__description("bounds check with JMP_NE for reg edge")
__success __retval(0)
__naked void reg_not_equal_const(void)
{
	asm volatile ("					\
	r6 = r1;					\
	r1 = 0;						\
	*(u64*)(r10 - 8) = r1;				\
	call %[bpf_get_prandom_u32];			\
	r4 = r0;					\
	r4 &= 7;					\
	if r4 != 0 goto l0_%=;				\
	r0 = 0;						\
	exit;						\
l0_%=:	r1 = r6;					\
	r2 = 0;						\
	r3 = r10;					\
	r3 += -8;					\
	r5 = 0;						\
	/* The 4th argument of bpf_skb_store_bytes is defined as \
	 * ARG_CONST_SIZE, so 0 is not allowed. The 'r4 != 0' \
	 * is providing us this exclusion of zero from initial \
	 * [0, 7] range.				\
	 */						\
	call %[bpf_skb_store_bytes];			\
	r0 = 0;						\
	exit;						\
"	:
	: __imm(bpf_get_prandom_u32),
	  __imm(bpf_skb_store_bytes)
	: __clobber_all);
}

SEC("tc")
__description("bounds check with JMP_EQ for reg edge")
__success __retval(0)
__naked void reg_equal_const(void)
{
	asm volatile ("					\
	r6 = r1;					\
	r1 = 0;						\
	*(u64*)(r10 - 8) = r1;				\
	call %[bpf_get_prandom_u32];			\
	r4 = r0;					\
	r4 &= 7;					\
	if r4 == 0 goto l0_%=;				\
	r1 = r6;					\
	r2 = 0;						\
	r3 = r10;					\
	r3 += -8;					\
	r5 = 0;						\
	/* Just the same as what we do in reg_not_equal_const() */ \
	call %[bpf_skb_store_bytes];			\
l0_%=:	r0 = 0;						\
	exit;						\
"	:
	: __imm(bpf_get_prandom_u32),
	  __imm(bpf_skb_store_bytes)
	: __clobber_all);
}

char _license[] SEC("license") = "GPL";