Skip to content

Commit 9d2cf5a

Browse files
anakryikogregkh
authored andcommitted
selftests/bpf: validate zero preservation for sub-slot loads
[ Upstream commit add1cd7 ] Validate that 1-, 2-, and 4-byte loads from stack slots not aligned on 8-byte boundary still preserve zero, when loading from all-STACK_ZERO sub-slots, or when stack sub-slots are covered by spilled register with known constant zero value. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20231205184248.1502704-8-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com> Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d3b398e commit 9d2cf5a

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

tools/testing/selftests/bpf/progs/verifier_spill_fill.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,4 +490,75 @@ __naked void spill_subregs_preserve_stack_zero(void)
490490
: __clobber_all);
491491
}
492492

493+
char single_byte_buf[1] SEC(".data.single_byte_buf");
494+
495+
SEC("raw_tp")
496+
__log_level(2)
497+
__success
498+
__naked void partial_stack_load_preserves_zeros(void)
499+
{
500+
asm volatile (
501+
/* fp-8 is all STACK_ZERO */
502+
".8byte %[fp8_st_zero];" /* LLVM-18+: *(u64 *)(r10 -8) = 0; */
503+
504+
/* fp-16 is const zero register */
505+
"r0 = 0;"
506+
"*(u64 *)(r10 -16) = r0;"
507+
508+
/* load single U8 from non-aligned STACK_ZERO slot */
509+
"r1 = %[single_byte_buf];"
510+
"r2 = *(u8 *)(r10 -1);"
511+
"r1 += r2;"
512+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
513+
514+
/* load single U8 from non-aligned ZERO REG slot */
515+
"r1 = %[single_byte_buf];"
516+
"r2 = *(u8 *)(r10 -9);"
517+
"r1 += r2;"
518+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
519+
520+
/* load single U16 from non-aligned STACK_ZERO slot */
521+
"r1 = %[single_byte_buf];"
522+
"r2 = *(u16 *)(r10 -2);"
523+
"r1 += r2;"
524+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
525+
526+
/* load single U16 from non-aligned ZERO REG slot */
527+
"r1 = %[single_byte_buf];"
528+
"r2 = *(u16 *)(r10 -10);"
529+
"r1 += r2;"
530+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
531+
532+
/* load single U32 from non-aligned STACK_ZERO slot */
533+
"r1 = %[single_byte_buf];"
534+
"r2 = *(u32 *)(r10 -4);"
535+
"r1 += r2;"
536+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
537+
538+
/* load single U32 from non-aligned ZERO REG slot */
539+
"r1 = %[single_byte_buf];"
540+
"r2 = *(u32 *)(r10 -12);"
541+
"r1 += r2;"
542+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
543+
544+
/* for completeness, load U64 from STACK_ZERO slot */
545+
"r1 = %[single_byte_buf];"
546+
"r2 = *(u64 *)(r10 -8);"
547+
"r1 += r2;"
548+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
549+
550+
/* for completeness, load U64 from ZERO REG slot */
551+
"r1 = %[single_byte_buf];"
552+
"r2 = *(u64 *)(r10 -16);"
553+
"r1 += r2;"
554+
"*(u8 *)(r1 + 0) = r2;" /* this should be fine */
555+
556+
"r0 = 0;"
557+
"exit;"
558+
:
559+
: __imm_ptr(single_byte_buf),
560+
__imm_insn(fp8_st_zero, BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0))
561+
: __clobber_common);
562+
}
563+
493564
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)