Add a verifier_spill_fill case that passes an untouched byte next to a
one-byte scalar spill to bpf_map_update_elem(). The full-capability load
retains the existing uninitialized-stack behavior, while the CAP_BPF-only
load must reject the STACK_INVALID helper read.

Signed-off-by: Yiyang Chen <[email protected]>
---
 .../selftests/bpf/progs/verifier_spill_fill.c | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c 
b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
index 8b166c42c4e0e..e686f6d8d5656 100644
--- a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
+++ b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
@@ -11,6 +11,13 @@ struct {
        __uint(max_entries, 4096);
 } map_ringbuf SEC(".maps");
 
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __type(key, __u32);
+       __type(value, __u8);
+} map_partial_spill SEC(".maps");
+
 SEC("socket")
 __description("check valid spill/fill")
 __success __failure_unpriv __msg_unpriv("R0 leaks addr")
@@ -1307,6 +1314,32 @@ __naked void 
stack_noperfmon_spill_32bit_onto_64bit_slot(void)
        : __clobber_all);
 }
 
+SEC("socket")
+__description("helper read must reject an invalid sibling of a narrow spill")
+__success
+__caps_unpriv(CAP_BPF)
+__failure_unpriv __msg_unpriv("invalid read from stack R3 off -7+0 size 1")
+__naked void helper_read_invalid_partial_spill_sibling(void)
+{
+       asm volatile ("r5 = 1;\n\t"
+       "*(u8 *)(r10 - 8) = r5;\n\t"
+       "r2 = 0;\n\t"
+       "*(u32 *)(r10 - 16) = r2;\n\t"
+       "r1 = %[map_partial_spill] ll;\n\t"
+       "r2 = r10;\n\t"
+       "r2 += -16;\n\t"
+       "r3 = r10;\n\t"
+       "r3 += -7;\n\t"
+       "r4 = 0;\n\t"
+       "call %[bpf_map_update_elem];\n\t"
+       "r0 = 0;\n\t"
+       "exit;\n\t"
+       :
+       : __imm(bpf_map_update_elem),
+         __imm_addr(map_partial_spill)
+       : __clobber_all);
+}
+
 /*
  * stacksafe(): check if 32-bit scalar spill in old state is considered
  * equivalent to STACK_MISC in cur state.
-- 
2.34.1


Reply via email to