mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 19:43:40 +02:00
selftests/bpf: Add test for Spectre v1 mitigation
This is based on the gadget from the description of commit 9183671af6db
("bpf: Fix leakage under speculation on mispredicted branches").
Signed-off-by: Luis Gerhorst <luis.gerhorst@fau.de>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20250603212814.338867-1-luis.gerhorst@fau.de
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
d6f1c85f22
commit
4a8765d9a5
|
|
@ -744,4 +744,61 @@ l0_%=: r0 = 0; \
|
|||
" ::: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("unpriv: Spectre v1 path-based type confusion of scalar as stack-ptr")
|
||||
__success __success_unpriv __retval(0)
|
||||
#ifdef SPEC_V1
|
||||
__xlated_unpriv("if r0 != 0x1 goto pc+2")
|
||||
/* This nospec prevents the exploit because it forces the mispredicted (not
|
||||
* taken) `if r0 != 0x0 goto l0_%=` to resolve before using r6 as a pointer.
|
||||
* This causes the CPU to realize that `r6 = r9` should have never executed. It
|
||||
* ensures that r6 always contains a readable stack slot ptr when the insn after
|
||||
* the nospec executes.
|
||||
*/
|
||||
__xlated_unpriv("nospec")
|
||||
__xlated_unpriv("r9 = *(u8 *)(r6 +0)")
|
||||
#endif
|
||||
__naked void unpriv_spec_v1_type_confusion(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u64*)(r10 - 8) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -8; \
|
||||
r1 = %[map_hash_8b] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 == 0 goto l2_%=; \
|
||||
/* r0: pointer to a map array entry */ \
|
||||
r2 = r10; \
|
||||
r2 += -8; \
|
||||
r1 = %[map_hash_8b] ll; \
|
||||
/* r1, r2: prepared call args */ \
|
||||
r6 = r10; \
|
||||
r6 += -8; \
|
||||
/* r6: pointer to readable stack slot */ \
|
||||
r9 = 0xffffc900; \
|
||||
r9 <<= 32; \
|
||||
/* r9: scalar controlled by attacker */ \
|
||||
r0 = *(u64 *)(r0 + 0); /* cache miss */ \
|
||||
if r0 != 0x0 goto l0_%=; \
|
||||
r6 = r9; \
|
||||
l0_%=: if r0 != 0x1 goto l1_%=; \
|
||||
r9 = *(u8 *)(r6 + 0); \
|
||||
l1_%=: /* leak r9 */ \
|
||||
r9 &= 1; \
|
||||
r9 <<= 9; \
|
||||
*(u64*)(r10 - 8) = r9; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 == 0 goto l2_%=; \
|
||||
/* leak secret into is_cached(map[0|512]): */ \
|
||||
r0 = *(u64 *)(r0 + 0); \
|
||||
l2_%=: \
|
||||
r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_hash_8b)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user