Skip to content

Nr #9198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed

Nr #9198

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -19955,11 +19955,11 @@ static int do_check(struct bpf_verifier_env *env)
/* Prevent this speculative path from ever reaching the
* insn that would have been unsafe to execute.
*/
cur_aux(env)->nospec = true;
env->insn_aux_data[prev_insn_idx].nospec = true;
/* If it was an ADD/SUB insn, potentially remove any
* markings for alu sanitization.
*/
cur_aux(env)->alu_state = 0;
env->insn_aux_data[prev_insn_idx].alu_state = 0;
goto process_bpf_exit;
} else if (err < 0) {
return err;
Expand All @@ -19968,7 +19968,7 @@ static int do_check(struct bpf_verifier_env *env)
}
WARN_ON_ONCE(err);

if (state->speculative && cur_aux(env)->nospec_result) {
if (state->speculative && env->insn_aux_data[prev_insn_idx].nospec_result) {
/* If we are on a path that performed a jump-op, this
* may skip a nospec patched-in after the jump. This can
* currently never happen because nospec_result is only
Expand All @@ -19977,6 +19977,8 @@ static int do_check(struct bpf_verifier_env *env)
* never skip the following insn. Still, add a warning
* to document this in case nospec_result is used
* elsewhere in the future.
*
* Therefore, no special case for ldimm64/call required.
*/
WARN_ON_ONCE(env->insn_idx != prev_insn_idx + 1);
process_bpf_exit:
Expand Down
4 changes: 4 additions & 0 deletions tools/testing/selftests/bpf/progs/bpf_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,8 @@
#define SPEC_V1
#endif

#if defined(__TARGET_ARCH_x86)
#define SPEC_V4
#endif

#endif
109 changes: 109 additions & 0 deletions tools/testing/selftests/bpf/progs/verifier_unpriv.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,4 +801,113 @@ l2_%=: \
: __clobber_all);
}

SEC("socket")
__description("ldimm64 nospec")
__success __success_unpriv
__retval(0)
#ifdef SPEC_V4
__xlated_unpriv("r1 = 0x2020200005642020")
__xlated_unpriv("*(u64 *)(r10 -8) = r1")
__xlated_unpriv("nospec")
#endif
__naked void ldimm64_nospec(void)
{
asm volatile (" \
r1 = 0x2020200005642020 ll; \
*(u64 *)(r10 -8) = r1; \
r0 = 0; \
exit; \
" ::: __clobber_all);
}

SEC("socket")
__description("spec_v4-induced path termination only after insn check")
__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 `*(u64 *)(NULL -64) = r1` iff
* `if r9 == 0 goto pc+4` was mispredicted because of Spectre v1
*/
__xlated_unpriv("nospec") /* Spectre v1 */
__xlated_unpriv("*(u64 *)(r2 -64) = r1")
__xlated_unpriv("nospec") /* Spectre v4 (nospec_result) */
#endif
#endif
__naked void v4_nospec_result_terminates_v1_path(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("spec_v4-induced path termination only after insn check (simplified, with dead code)")
__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") /* if r9 == 0 goto l3_%= */
__xlated_unpriv("goto pc+2") /* goto l2_%= */
__xlated_unpriv("goto pc-1") /* if r9 == 0 goto l3_%= */
__xlated_unpriv("goto pc-1") /* r2 = r0 */
__xlated_unpriv("nospec") /* Spectre v1 */
__xlated_unpriv("*(u64 *)(r2 -64) = r1")
__xlated_unpriv("nospec") /* Spectre v4 (nospec_result) */
#endif
#endif
__naked void v4_nospec_result_terminates_v1_path_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);
}

char _license[] SEC("license") = "GPL";
Loading