From nobody Wed Oct 8 11:40:08 2025 Received: from mx-rz-3.rrze.uni-erlangen.de (mx-rz-3.rrze.uni-erlangen.de [131.188.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 825A21FECB1; Sat, 28 Jun 2025 14:54:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=131.188.11.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122449; cv=none; b=cKIQLfHBD1pjSyDyw+HBVN0Qzgig+sCSNMEB2MvTK6Yjkq+5Q2r7VuCLSOVG36rItoRYnbBMLog+8SMJsUWpn1/0ve3k1mpGug7wDJ87WMifrWuWSUTgfRrSZVIFLWMlLmcqfhz8VO+18PX7LOhkFDP8PVz+4T3XWnNbKuE+Iss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122449; c=relaxed/simple; bh=p9Kc25E1/YhQv8Ncgikbiw3FqAZ+Fg2257/hti0eskI=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WkDocSSoVX7OtnGXMhNelMOJj1fI/WnJjd1zXVa3OayYR0n5mB8VNYeVUqSuOdgMaOHbUIyh5qsnaOVTGcXLCR7Q7XQnnObu7T0FtSo14Wow/RbncghUCbyTigJ4mkjuDJ0lm9AaQfKAQzgV6n5Z0ogP3Q4orZjNtKhWqHjxMmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de; spf=pass smtp.mailfrom=fau.de; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b=slWecvgk; arc=none smtp.client-ip=131.188.11.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fau.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b="slWecvgk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fau.de; s=fau-2021; t=1751122439; bh=HVuOgJb1q9Zwq0pkkf+xWEQsM3tYtFZlV1G9CpuqQEQ=; h=From:To:Subject:Date:In-Reply-To:References:From:To:CC:Subject; b=slWecvgk94HCsxmaxZdUOHXSWP9Tiau5Z8OVgaPLslm7eBnYn4KctOjiU9ph3d2cD 1jm8vUwKZ0ePOTGUJ04VPV6hdXEKY7/lAb+h3VOTTMIxcUPWRjzFjib/LslUGWjuSZ GCN3s57YfvRHfyL1ajOjhZnaDu27hASyXwmZuEBS1jwG/I1YJcQz+up8yw7g+Nec+4 vsh/qpTYv7PYFW2nPM0k9ejfLNekVmdbAfTUL9x6t0gKZPPO50L826CpDmxzrrlx0b 4VuFBMX9H9dtoQXY1BiMYQ73CwBKXNImUGp+8S5XMA8Pe3N5wRjVCh3o5MWbx6hcaS 1OIJIuxoh7OsQ== Received: from mx-rz-smart.rrze.uni-erlangen.de (mx-rz-smart.rrze.uni-erlangen.de [IPv6:2001:638:a000:1025::1e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-rz-3.rrze.uni-erlangen.de (Postfix) with ESMTPS id 4bTwRW28C0z1yYg; Sat, 28 Jun 2025 16:53:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at boeck5.rrze.uni-erlangen.de (RRZE) X-RRZE-Flag: Not-Spam X-RRZE-Submit-IP: 2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9 Received: from luis-tp.fritz.box (unknown [IPv6:2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: U2FsdGVkX1+s4h/sPgxfq6XxQLskiZQotQ0zVKqBPCw=) by smtp-auth.uni-erlangen.de (Postfix) with ESMTPSA id 4bTwRR4WLYz1y1R; Sat, 28 Jun 2025 16:53:55 +0200 (CEST) From: Luis Gerhorst To: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Kumar Kartikeya Dwivedi , Luis Gerhorst , Peilin Ye , Jiayuan Chen , Saket Kumar Bhaskar , Ihor Solodrai , Daniel Xu , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Chaignon Subject: [PATCH bpf-next v2 1/3] bpf: Update env->prev_insn_idx after do_check_insn() Date: Sat, 28 Jun 2025 16:50:14 +0200 Message-ID: <20250628145016.784256-2-luis.gerhorst@fau.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250628145016.784256-1-luis.gerhorst@fau.de> References: <20250628145016.784256-1-luis.gerhorst@fau.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To introduce prev_aux(env), env->prev_insn_idx must be up-to-date directly after do_check_insn(). To achieve this, replace prev_insn_idx with a tmp variable (to discourage use) and update env->prev_insn_idx directly after do_check_insn(). A concern would be that some code relied on env->prev_insn_idx still having the old value between do_check_insn() and the old update-assignment. However, outside the do_check() function it is only used through push_jmp_history()/do_check_insn()/is_state_visisted() which are not called in-between the old and new assignment location. This can also be seen from the -O0 call graph for push_jmp_history() [1]. [1] https://sys.cs.fau.de/extern/person/gerhorst/25-06_d69baf_push_jmp_hist= ory_O0_callgraph.png Signed-off-by: Luis Gerhorst --- kernel/bpf/verifier.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index f403524bd215..b33bc37d5372 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -19854,16 +19854,15 @@ static int do_check(struct bpf_verifier_env *env) struct bpf_insn *insns =3D env->prog->insnsi; int insn_cnt =3D env->prog->len; bool do_print_state =3D false; - int prev_insn_idx =3D -1; =20 + env->prev_insn_idx =3D -1; for (;;) { struct bpf_insn *insn; - int err; + int err, tmp; =20 /* reset current history entry on each new instruction */ env->cur_hist_ent =3D NULL; =20 - env->prev_insn_idx =3D prev_insn_idx; if (env->insn_idx >=3D insn_cnt) { verbose(env, "invalid insn idx %d insn_cnt %d\n", env->insn_idx, insn_cnt); @@ -19942,7 +19941,6 @@ static int do_check(struct bpf_verifier_env *env) } =20 sanitize_mark_insn_seen(env); - prev_insn_idx =3D env->insn_idx; =20 /* Reduce verification complexity by stopping speculative path * verification when a nospec is encountered. @@ -19950,7 +19948,9 @@ static int do_check(struct bpf_verifier_env *env) if (state->speculative && cur_aux(env)->nospec) goto process_bpf_exit; =20 + tmp =3D env->insn_idx; err =3D do_check_insn(env, &do_print_state); + env->prev_insn_idx =3D tmp; if (error_recoverable_with_nospec(err) && state->speculative) { /* Prevent this speculative path from ever reaching the * insn that would have been unsafe to execute. @@ -19978,13 +19978,13 @@ static int do_check(struct bpf_verifier_env *env) * to document this in case nospec_result is used * elsewhere in the future. */ - WARN_ON_ONCE(env->insn_idx !=3D prev_insn_idx + 1); + WARN_ON_ONCE(env->insn_idx !=3D env->prev_insn_idx + 1); process_bpf_exit: mark_verifier_state_scratched(env); err =3D update_branch_counts(env, env->cur_state); if (err) return err; - err =3D pop_stack(env, &prev_insn_idx, &env->insn_idx, + err =3D pop_stack(env, &env->prev_insn_idx, &env->insn_idx, pop_log); if (err < 0) { if (err !=3D -ENOENT) --=20 2.49.0 From nobody Wed Oct 8 11:40:08 2025 Received: from mx-rz-2.rrze.uni-erlangen.de (mx-rz-2.rrze.uni-erlangen.de [131.188.11.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 852FA24E016; Sat, 28 Jun 2025 14:57:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=131.188.11.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122665; cv=none; b=MAacog6ViJRxBeQAW4OhGmKc6adK7+W84b1jQ0mgpJL6lHNWt7rNwm1x3+hp7e2mWLmyXFyJtN2A+i/OSFIQhmppHtkRemBdKPvcwq/OFRiH5dpLsyYI5mxtOfRU11CRa9Q5P0ec2vKshK+8tZ0YKqzaou8w8UI+6yKhjZgt3Q0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122665; c=relaxed/simple; bh=HSi06s+PUGxdJBGY6GFxak4sv815cnWzv1NhWB8k274=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=okcejhClzTjC4mUE10AoGcxR+Kzu6JJww1wQzqDXwM7JzqroZ9QYqmUi05DpGHtq3O9A/bAigwYwiufTGodf5TSBeoIjIEGY1MR6E0q5uvaZuw+Ocl6hThEXlallebbKZE9UH5oOdU+teYVtUMuC7SnWzE2hfPbIW+rb2Q0byxI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de; spf=pass smtp.mailfrom=fau.de; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b=ynTWNJtw; arc=none smtp.client-ip=131.188.11.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fau.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b="ynTWNJtw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fau.de; s=fau-2021; t=1751122661; bh=fBaRk57nz6ElXpESIpcHM6WYYqzGAzZVyIAI++LaDzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:To:CC: Subject; b=ynTWNJtwzE/kdD8Cgw6335AZ8YpOEyuaH+gya+a7LAKfsbWAHnuDlxLRSIsfhHx6S 1B3d0ZfzYsMD0xlZ62gaOj4bCDD+3QkJ9r2NumRQQW3vtZ1Xc7HYsNXrGf0YtUCKst EO9WY2b0GiWixZDHzjppuf+xGrNsPrUvA0otTi46PwpYkjIaGHQ2vOxGtzl7w9Du8k cNaWmZ5CmZW0Xn9f+R7PVGL5rH9xLKYaHn+EpWrktZZK41wR5B/UDur3rMVwnp1uTC LEBtd/tSThOiyvK/zDE1thr4qw/oFO6QyENKO7udEEHNsdAOEq32HLOanlik9W6P6T tUnAT4yMOsrzA== Received: from mx-rz-smart.rrze.uni-erlangen.de (mx-rz-smart.rrze.uni-erlangen.de [IPv6:2001:638:a000:1025::1e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-rz-2.rrze.uni-erlangen.de (Postfix) with ESMTPS id 4bTwWn2G2bzPklm; Sat, 28 Jun 2025 16:57:41 +0200 (CEST) X-Virus-Scanned: amavisd-new at boeck5.rrze.uni-erlangen.de (RRZE) X-RRZE-Flag: Not-Spam X-RRZE-Submit-IP: 2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9 Received: from luis-tp.fritz.box (unknown [IPv6:2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: U2FsdGVkX18H9PD/qK7m2EViWUok2doCQe0kVAsTFqg=) by smtp-auth.uni-erlangen.de (Postfix) with ESMTPSA id 4bTwWj6gbRzPkB5; Sat, 28 Jun 2025 16:57:37 +0200 (CEST) From: Luis Gerhorst To: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Kumar Kartikeya Dwivedi , Luis Gerhorst , Peilin Ye , Jiayuan Chen , Saket Kumar Bhaskar , Ihor Solodrai , Daniel Xu , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Chaignon Cc: syzbot+dc27c5fb8388e38d2d37@syzkaller.appspotmail.com Subject: [PATCH bpf-next v2 2/3] bpf: Fix aux usage after do_check_insn() Date: Sat, 28 Jun 2025 16:50:15 +0200 Message-ID: <20250628145016.784256-3-luis.gerhorst@fau.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250628145016.784256-1-luis.gerhorst@fau.de> References: <20250628145016.784256-1-luis.gerhorst@fau.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" We must terminate the speculative analysis if the just-analyzed insn had nospec_result set. Using cur_aux() here is wrong because insn_idx might have been incremented by do_check_insn(). Therefore, introduce and use prev_aux(). Also change cur_aux(env)->nospec in case do_check_insn() ever manages to increment insn_idx but still fail. Change the warning to check the insn class (which prevents it from triggering for ldimm64, for which nospec_result would not be problematic) and use verifier_bug_if(). Fixes: d6f1c85f2253 ("bpf: Fall back to nospec for Spectre v1") Reported-by: Paul Chaignon Reported-by: Eduard Zingerman Reported-by: syzbot+dc27c5fb8388e38d2d37@syzkaller.appspotmail.com Link: https://lore.kernel.org/bpf/685b3c1b.050a0220.2303ee.0010.GAE@google.= com/ Link: https://lore.kernel.org/bpf/4266fd5de04092aa4971cbef14f1b4b96961f432.= camel@gmail.com/ Signed-off-by: Luis Gerhorst --- kernel/bpf/verifier.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index b33bc37d5372..9d066e4b8248 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11216,6 +11216,11 @@ static struct bpf_insn_aux_data *cur_aux(const str= uct bpf_verifier_env *env) return &env->insn_aux_data[env->insn_idx]; } =20 +static struct bpf_insn_aux_data *prev_aux(const struct bpf_verifier_env *e= nv) +{ + return &env->insn_aux_data[env->prev_insn_idx]; +} + static bool loop_flag_is_zero(struct bpf_verifier_env *env) { struct bpf_reg_state *regs =3D cur_regs(env); @@ -19955,11 +19960,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 =3D true; + prev_aux(env)->nospec =3D true; /* If it was an ADD/SUB insn, potentially remove any * markings for alu sanitization. */ - cur_aux(env)->alu_state =3D 0; + prev_aux(env)->alu_state =3D 0; goto process_bpf_exit; } else if (err < 0) { return err; @@ -19968,7 +19973,7 @@ static int do_check(struct bpf_verifier_env *env) } WARN_ON_ONCE(err); =20 - if (state->speculative && cur_aux(env)->nospec_result) { + if (state->speculative && prev_aux(env)->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 @@ -19977,8 +19982,15 @@ 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. + * + * All non-branch instructions have a single + * fall-through edge. For these, nospec_result should + * already work. */ - WARN_ON_ONCE(env->insn_idx !=3D env->prev_insn_idx + 1); + if (verifier_bug_if(BPF_CLASS(insn->code) =3D=3D BPF_JMP || + BPF_CLASS(insn->code) =3D=3D BPF_JMP32, env, + "speculation barrier after jump instruction may not have the desi= red effect")) + return -EFAULT; process_bpf_exit: mark_verifier_state_scratched(env); err =3D update_branch_counts(env, env->cur_state); --=20 2.49.0 From nobody Wed Oct 8 11:40:08 2025 Received: from mx-rz-1.rrze.uni-erlangen.de (mx-rz-1.rrze.uni-erlangen.de [131.188.11.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE61415DBB3; Sat, 28 Jun 2025 15:01:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=131.188.11.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122920; cv=none; b=KpYjJRp9DUv3FJAj+UR9iW2JEeu6zTU02QpHVZEKTUzRlp7P5S/eFj+HT2aXOqlQMmCi+4kh7rt55J1tsidcOSKNPoOIimGe4Vl1OM4Fojq93DPBHfhmEomD4P80zaQUk1u+HpkiSF895PjmPDyDjCfDAn153AygNUZPBFcMTZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751122920; c=relaxed/simple; bh=JYSr+4axxHIotvpxTe4hIWmAX2B/c5uvK0LSS2w+C3Q=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jJR1m4vVeB7EpJgc96TN5eFcpv32dmq0Pd4LvbznBMjXQ+klH8LjofMTuuWpXmqK9zTI5pcS0d6egWyWrunVYO+R6HMjtgjDGXQbwBgQWC2CyyKTmEqCA3nQMR4othqC9Zfnw2dL4yfCRfKOdAEMZ5cqB1RXC1i7tmSZJ0yyh74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de; spf=pass smtp.mailfrom=fau.de; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b=z1CxaaF9; arc=none smtp.client-ip=131.188.11.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=fau.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fau.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fau.de header.i=@fau.de header.b="z1CxaaF9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fau.de; s=fau-2021; t=1751122916; bh=rcqvB24Pyxx9S4coBRICiUhH7Jgty3vrOBOTtW7/DS4=; h=From:To:Subject:Date:In-Reply-To:References:From:To:CC:Subject; b=z1CxaaF9NsGWMH3jmIMb7iEKyZ2ye4UdsaLIcIPH7vV14CGLm8/9Kf7XD6MXr4ELP J+TEj+EKt463xDv9zDqb3pRGzdbBl30jhmC541/kREwC53SVN7OxcUO8BJA6/SJJxg VyEfVE49AzqkoSrxFNcZ1nNRr0VWi/lh3+0jqLyYaLRTSlYBdqh0n/Dq3swMDLhrNf +1NqrAs+ELXUTpbHhrjiGpFXA0RTjFPqd/BDr5Lh04ApnS7Q+dpRcBvglx6Q0H2EXY Gb4g8qkiXyv5YLai8I39T0II1ul/cFANLY2coXPAWTxQdxdymxmuwWB0JXJnyI3iK4 2uQQF2Yci9GJA== Received: from mx-rz-smart.rrze.uni-erlangen.de (mx-rz-smart.rrze.uni-erlangen.de [IPv6:2001:638:a000:1025::1e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-rz-1.rrze.uni-erlangen.de (Postfix) with ESMTPS id 4bTwch4h5Zz8v7p; Sat, 28 Jun 2025 17:01:56 +0200 (CEST) X-Virus-Scanned: amavisd-new at boeck1.rrze.uni-erlangen.de (RRZE) X-RRZE-Flag: Not-Spam X-RRZE-Submit-IP: 2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9 Received: from luis-tp.fritz.box (unknown [IPv6:2001:9e8:3601:f400:3a2b:2f7e:18b0:5ef9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: U2FsdGVkX1+gFv4becOpWZ+vsA9E7Nstjmq1QxCJIsQ=) by smtp-auth.uni-erlangen.de (Postfix) with ESMTPSA id 4bTwcd0wD5z8sgD; Sat, 28 Jun 2025 17:01:53 +0200 (CEST) From: Luis Gerhorst To: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Kumar Kartikeya Dwivedi , Luis Gerhorst , Peilin Ye , Jiayuan Chen , Saket Kumar Bhaskar , Ihor Solodrai , Daniel Xu , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Chaignon Subject: [PATCH bpf-next v2 3/3] selftests/bpf: Add Spectre v4 tests Date: Sat, 28 Jun 2025 16:50:16 +0200 Message-ID: <20250628145016.784256-4-luis.gerhorst@fau.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250628145016.784256-1-luis.gerhorst@fau.de> References: <20250628145016.784256-1-luis.gerhorst@fau.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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.ca= mel@gmail.com/ [2] https://lore.kernel.org/bpf/685b3c1b.050a0220.2303ee.0010.GAE@google.co= m/ Signed-off-by: Luis Gerhorst --- tools/testing/selftests/bpf/progs/bpf_misc.h | 4 + .../selftests/bpf/progs/verifier_unpriv.c | 149 ++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/s= elftests/bpf/progs/bpf_misc.h index a678463e972c..be7d9bfa8390 100644 --- a/tools/testing/selftests/bpf/progs/bpf_misc.h +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h @@ -235,4 +235,8 @@ #define SPEC_V1 #endif =20 +#if defined(__TARGET_ARCH_x86) +#define SPEC_V4 +#endif + #endif diff --git a/tools/testing/selftests/bpf/progs/verifier_unpriv.c b/tools/te= sting/selftests/bpf/progs/verifier_unpriv.c index 4470541b5e71..28b4f7035ceb 100644 --- a/tools/testing/selftests/bpf/progs/verifier_unpriv.c +++ b/tools/testing/selftests/bpf/progs/verifier_unpriv.c @@ -801,4 +801,153 @@ l2_%=3D: \ : __clobber_all); } =20 +SEC("socket") +__description("unpriv: ldimm64 before Spectre v4 barrier") +__success __success_unpriv +__retval(0) +#ifdef SPEC_V4 +__xlated_unpriv("r1 =3D 0x2020200005642020") /* should not matter */ +__xlated_unpriv("*(u64 *)(r10 -8) =3D r1") +__xlated_unpriv("nospec") +#endif +__naked void unpriv_ldimm64_spectre_v4(void) +{ + asm volatile (" \ + r1 =3D 0x2020200005642020 ll; \ + *(u64 *)(r10 -8) =3D r1; \ + r0 =3D 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 =3D=3D r8 =3D=3D r9 =3D=3D 0 */ +__xlated_unpriv("if r8 !=3D 0x0 goto pc+1") +__xlated_unpriv("goto pc+2") +__xlated_unpriv("if r9 =3D=3D 0x0 goto pc+4") +__xlated_unpriv("r2 =3D r0") +/* Following nospec required to prevent following dangerous `*(u64 *)(NOT_= FP -64) + * =3D r1` iff `if r9 =3D=3D 0 goto pc+4` was mispredicted because of Spec= tre 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) =3D 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 =3D 0; \ + *(u64*)(r10 - 8) =3D r1; \ + r2 =3D r10; \ + r2 +=3D -8; \ + r1 =3D %[map_hash_8b] ll; \ + call %[bpf_map_lookup_elem]; \ + r8 =3D r0; \ + r2 =3D r10; \ + r2 +=3D -8; \ + r1 =3D %[map_hash_8b] ll; \ + call %[bpf_map_lookup_elem]; \ + r9 =3D r0; \ + r0 =3D r10; \ + r1 =3D 0; \ + r2 =3D r10; \ + if r8 !=3D 0 goto l0_%=3D; \ + if r9 !=3D 0 goto l0_%=3D; \ + r0 =3D 0; \ +l0_%=3D: if r8 !=3D 0 goto l1_%=3D; \ + goto l2_%=3D; \ +l1_%=3D: if r9 =3D=3D 0 goto l3_%=3D; \ + r2 =3D r0; \ +l2_%=3D: *(u64 *)(r2 -64) =3D r1; \ +l3_%=3D: r0 =3D 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 !=3D 0x0 goto pc+1") +__xlated_unpriv("goto pc+2") +__xlated_unpriv("goto pc-1") /* if r9 =3D=3D 0 goto l3_%=3D */ +__xlated_unpriv("goto pc-1") /* r2 =3D r0 */ +__xlated_unpriv("nospec") +__xlated_unpriv("*(u64 *)(r2 -64) =3D r1") +__xlated_unpriv("nospec") +#endif +#endif +__naked void unpriv_spectre_v1_and_v4_simple(void) +{ + asm volatile (" \ + r8 =3D 0; \ + r9 =3D 0; \ + r0 =3D r10; \ + r1 =3D 0; \ + r2 =3D r10; \ + if r8 !=3D 0 goto l0_%=3D; \ + if r9 !=3D 0 goto l0_%=3D; \ + r0 =3D 0; \ +l0_%=3D: if r8 !=3D 0 goto l1_%=3D; \ + goto l2_%=3D; \ +l1_%=3D: if r9 =3D=3D 0 goto l3_%=3D; \ + r2 =3D r0; \ +l2_%=3D: *(u64 *)(r2 -64) =3D r1; \ +l3_%=3D: r0 =3D 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 !=3D 0x0 goto pc+1") +__xlated_unpriv("goto pc+4") +__xlated_unpriv("goto pc-1") /* if r9 =3D=3D 0 goto l3_%=3D */ +__xlated_unpriv("goto pc-1") /* r2 =3D r0 */ +__xlated_unpriv("goto pc-1") /* r1 =3D 0x2020200005642020 ll */ +__xlated_unpriv("goto pc-1") /* second part of ldimm64 */ +__xlated_unpriv("nospec") +__xlated_unpriv("*(u64 *)(r2 -64) =3D r1") +__xlated_unpriv("nospec") +#endif +#endif +__naked void unpriv_ldimm64_spectre_v1_and_v4_simple(void) +{ + asm volatile (" \ + r8 =3D 0; \ + r9 =3D 0; \ + r0 =3D r10; \ + r1 =3D 0; \ + r2 =3D r10; \ + if r8 !=3D 0 goto l0_%=3D; \ + if r9 !=3D 0 goto l0_%=3D; \ + r0 =3D 0; \ +l0_%=3D: if r8 !=3D 0 goto l1_%=3D; \ + goto l2_%=3D; \ +l1_%=3D: if r9 =3D=3D 0 goto l3_%=3D; \ + r2 =3D r0; \ + r1 =3D 0x2020200005642020 ll; \ +l2_%=3D: *(u64 *)(r2 -64) =3D r1; \ +l3_%=3D: r0 =3D 0; \ + exit; \ +" ::: __clobber_all); +} + char _license[] SEC("license") =3D "GPL"; --=20 2.49.0