Re: [RFC PATCH bpf-next v1 2/2] selftests/bpf: Add selftest for bpf_dynptr_slice_rdwr r0 handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2025-02-19 at 04:51 -0800, Kumar Kartikeya Dwivedi wrote:
> Ensure that once we get the return value and write to a stack slot it
> may potentially alias, we don't get confused about the state of the
> stack. Without the fix in the previous patch, we will assume the load
> from r8 into r0 before will always be from a map value, but in the case
> where the returned value is the passed in buffer, we're writing to fp-8
> and will overwrite the map value stored there.
> 
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx>
> ---
>  .../testing/selftests/bpf/progs/dynptr_fail.c | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/progs/dynptr_fail.c b/tools/testing/selftests/bpf/progs/dynptr_fail.c
> index bd8f15229f5c..4584bf53c5f8 100644
> --- a/tools/testing/selftests/bpf/progs/dynptr_fail.c
> +++ b/tools/testing/selftests/bpf/progs/dynptr_fail.c
> @@ -1735,3 +1735,48 @@ int test_dynptr_reg_type(void *ctx)
>  	global_call_bpf_dynptr((const struct bpf_dynptr *)current);
>  	return 0;
>  }
> +
> +SEC("?tc")
> +__failure __msg("R8 invalid mem access 'scalar'") __log_level(2)
> +int dynptr_slice_rdwr_overwrite(struct __sk_buff *ctx)
> +{
> +	asm volatile (

Nit: having a few comments with equivalent C code would help
     understand this test case.

> +		"r6 = %[array_map4] ll;			\
> +		 r9 = r1;				\
> +		 r1 = r6;				\
> +		 r2 = r10;				\
> +		 r2 += -8;				\
> +		 call %[bpf_map_lookup_elem];		\
> +		 if r0 == 0 goto rjmp1;			\
> +		 *(u64 *)(r10 - 8) = r0;		\
> +		 r8 = r0;				\
> +		 r1 = r9;				\
> +		 r2 = 0;				\
> +		 r3 = r10;				\
> +		 r3 += -24;				\
> +		 call %[bpf_dynptr_from_skb];		\
> +		 r1 = r10;				\
> +		 r1 += -24;				\
> +		 r2 = 0;				\
> +		 r3 = r10;				\
> +		 r3 += -8;				\
> +		 r4 = 8;				\
> +		 call %[bpf_dynptr_slice_rdwr];		\
> +		 if r0 == 0 goto rjmp1;			\
> +		 r1 = 0;				\
> +		 *(u64 *)(r10 - 8) = r8;		\
> +		 *(u64 *)(r0 + 0) = r1;			\
> +		 r8 = *(u64 *)(r10 - 8);		\
> +		 r0 = *(u64 *)(r8 + 0);			\
> +	rjmp1:						\

Note: 'rjmp1' would be a global label.
      An alternative would be to either use 'goto 1f' and label '1:',
      or use the '%=' counter: 'goto rjmp1_%=', 'rjmp_%=:'.
      These would make label names unique for this inline assembly block.
      See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Special-format-strings ,
      And https://sourceware.org/binutils/docs/as/Symbol-Names.html .

> +		 r0 = 0;				\
> +		 "
> +		:
> +		: __imm(bpf_map_lookup_elem),
> +		  __imm(bpf_dynptr_from_skb),
> +		  __imm(bpf_dynptr_slice_rdwr),
> +		  __imm_addr(array_map4)
> +		: __clobber_all
> +	);
> +	return 0;
> +}







[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux