mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
selftests/bpf: Add Spectre v4 tests
Add the following tests: 1. A test with an (unimportant) ldimm64 (16 byte insn) and a Spectre-v4--induced nospec that clarifies and serves as a basic Spectre v4 test. 2. Make sure a Spectre v4 nospec_result does not prevent a Spectre v1 nospec from being added before the dangerous instruction (tests that [1] is fixed). 3. Combine the two, which is the combination that triggers the warning in [2]. This is because the unanalyzed stack write has nospec_result set, but the ldimm64 (which was just analyzed) had incremented insn_idx by 2. That violates the assertion that nospec_result is only used after insns that increment insn_idx by 1 (i.e., stack writes). [1] https://lore.kernel.org/bpf/4266fd5de04092aa4971cbef14f1b4b96961f432.camel@gmail.com/ [2] https://lore.kernel.org/bpf/685b3c1b.050a0220.2303ee.0010.GAE@google.com/ Signed-off-by: Luis Gerhorst <luis.gerhorst@fau.de> Link: https://lore.kernel.org/r/20250705190908.1756862-3-luis.gerhorst@fau.de Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
dadb59104c
commit
92974cef83
|
|
@ -237,4 +237,8 @@
|
|||
#define SPEC_V1
|
||||
#endif
|
||||
|
||||
#if defined(__TARGET_ARCH_x86)
|
||||
#define SPEC_V4
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -801,4 +801,153 @@ l2_%=: \
|
|||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("unpriv: ldimm64 before Spectre v4 barrier")
|
||||
__success __success_unpriv
|
||||
__retval(0)
|
||||
#ifdef SPEC_V4
|
||||
__xlated_unpriv("r1 = 0x2020200005642020") /* should not matter */
|
||||
__xlated_unpriv("*(u64 *)(r10 -8) = r1")
|
||||
__xlated_unpriv("nospec")
|
||||
#endif
|
||||
__naked void unpriv_ldimm64_spectre_v4(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0x2020200005642020 ll; \
|
||||
*(u64 *)(r10 -8) = r1; \
|
||||
r0 = 0; \
|
||||
exit; \
|
||||
" ::: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("unpriv: Spectre v1 and v4 barrier")
|
||||
__success __success_unpriv
|
||||
__retval(0)
|
||||
#ifdef SPEC_V1
|
||||
#ifdef SPEC_V4
|
||||
/* starts with r0 == r8 == r9 == 0 */
|
||||
__xlated_unpriv("if r8 != 0x0 goto pc+1")
|
||||
__xlated_unpriv("goto pc+2")
|
||||
__xlated_unpriv("if r9 == 0x0 goto pc+4")
|
||||
__xlated_unpriv("r2 = r0")
|
||||
/* Following nospec required to prevent following dangerous `*(u64 *)(NOT_FP -64)
|
||||
* = r1` iff `if r9 == 0 goto pc+4` was mispredicted because of Spectre v1. The
|
||||
* test therefore ensures the Spectre-v4--induced nospec does not prevent the
|
||||
* Spectre-v1--induced speculative path from being fully analyzed.
|
||||
*/
|
||||
__xlated_unpriv("nospec") /* Spectre v1 */
|
||||
__xlated_unpriv("*(u64 *)(r2 -64) = r1") /* could be used to leak r2 */
|
||||
__xlated_unpriv("nospec") /* Spectre v4 */
|
||||
#endif
|
||||
#endif
|
||||
__naked void unpriv_spectre_v1_and_v4(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u64*)(r10 - 8) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -8; \
|
||||
r1 = %[map_hash_8b] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
r8 = r0; \
|
||||
r2 = r10; \
|
||||
r2 += -8; \
|
||||
r1 = %[map_hash_8b] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
r9 = r0; \
|
||||
r0 = r10; \
|
||||
r1 = 0; \
|
||||
r2 = r10; \
|
||||
if r8 != 0 goto l0_%=; \
|
||||
if r9 != 0 goto l0_%=; \
|
||||
r0 = 0; \
|
||||
l0_%=: if r8 != 0 goto l1_%=; \
|
||||
goto l2_%=; \
|
||||
l1_%=: if r9 == 0 goto l3_%=; \
|
||||
r2 = r0; \
|
||||
l2_%=: *(u64 *)(r2 -64) = r1; \
|
||||
l3_%=: r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_hash_8b)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("unpriv: Spectre v1 and v4 barrier (simple)")
|
||||
__success __success_unpriv
|
||||
__retval(0)
|
||||
#ifdef SPEC_V1
|
||||
#ifdef SPEC_V4
|
||||
__xlated_unpriv("if r8 != 0x0 goto pc+1")
|
||||
__xlated_unpriv("goto pc+2")
|
||||
__xlated_unpriv("goto pc-1") /* if r9 == 0 goto l3_%= */
|
||||
__xlated_unpriv("goto pc-1") /* r2 = r0 */
|
||||
__xlated_unpriv("nospec")
|
||||
__xlated_unpriv("*(u64 *)(r2 -64) = r1")
|
||||
__xlated_unpriv("nospec")
|
||||
#endif
|
||||
#endif
|
||||
__naked void unpriv_spectre_v1_and_v4_simple(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r8 = 0; \
|
||||
r9 = 0; \
|
||||
r0 = r10; \
|
||||
r1 = 0; \
|
||||
r2 = r10; \
|
||||
if r8 != 0 goto l0_%=; \
|
||||
if r9 != 0 goto l0_%=; \
|
||||
r0 = 0; \
|
||||
l0_%=: if r8 != 0 goto l1_%=; \
|
||||
goto l2_%=; \
|
||||
l1_%=: if r9 == 0 goto l3_%=; \
|
||||
r2 = r0; \
|
||||
l2_%=: *(u64 *)(r2 -64) = r1; \
|
||||
l3_%=: r0 = 0; \
|
||||
exit; \
|
||||
" ::: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("unpriv: ldimm64 before Spectre v1 and v4 barrier (simple)")
|
||||
__success __success_unpriv
|
||||
__retval(0)
|
||||
#ifdef SPEC_V1
|
||||
#ifdef SPEC_V4
|
||||
__xlated_unpriv("if r8 != 0x0 goto pc+1")
|
||||
__xlated_unpriv("goto pc+4")
|
||||
__xlated_unpriv("goto pc-1") /* if r9 == 0 goto l3_%= */
|
||||
__xlated_unpriv("goto pc-1") /* r2 = r0 */
|
||||
__xlated_unpriv("goto pc-1") /* r1 = 0x2020200005642020 ll */
|
||||
__xlated_unpriv("goto pc-1") /* second part of ldimm64 */
|
||||
__xlated_unpriv("nospec")
|
||||
__xlated_unpriv("*(u64 *)(r2 -64) = r1")
|
||||
__xlated_unpriv("nospec")
|
||||
#endif
|
||||
#endif
|
||||
__naked void unpriv_ldimm64_spectre_v1_and_v4_simple(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r8 = 0; \
|
||||
r9 = 0; \
|
||||
r0 = r10; \
|
||||
r1 = 0; \
|
||||
r2 = r10; \
|
||||
if r8 != 0 goto l0_%=; \
|
||||
if r9 != 0 goto l0_%=; \
|
||||
r0 = 0; \
|
||||
l0_%=: if r8 != 0 goto l1_%=; \
|
||||
goto l2_%=; \
|
||||
l1_%=: if r9 == 0 goto l3_%=; \
|
||||
r2 = r0; \
|
||||
r1 = 0x2020200005642020 ll; \
|
||||
l2_%=: *(u64 *)(r2 -64) = r1; \
|
||||
l3_%=: r0 = 0; \
|
||||
exit; \
|
||||
" ::: __clobber_all);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user