bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v3 0/1] selftests/bpf: more precise cpu_mitigations state detection
@ 2025-06-17  0:57 Eduard Zingerman
  2025-06-17  0:57 ` [PATCH bpf-next v3 1/1] " Eduard Zingerman
  2025-06-17 20:30 ` [PATCH bpf-next v3 0/1] " patchwork-bot+netdevbpf
  0 siblings, 2 replies; 3+ messages in thread
From: Eduard Zingerman @ 2025-06-17  0:57 UTC (permalink / raw)
  To: bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87,
	laoar.shao, mykyta.yatsenko5

If kernel executing selftests is configured with spectre mitigations
disabled, verification of unprivileged BPF won't emulate speculative
branches.

A number of selftests relies on speculative branches being visited.
In discussion [1] it was decided not to add additional tests
classification, but to execute unprivileged tests only when
mitigations are enabled.

Current mitigations status detection inspects /proc/cmdline,
which is not sufficient for some configurations.
This patch adds logic to also inspect /proc/config.gz and
/boot/config-$(uname -r).

Changelog:
v2: https://lore.kernel.org/bpf/20250614050617.4161083-1-eddyz87@gmail.com/
v2 -> v3:
- stylistic changes (Andrii).

v1: https://lore.kernel.org/bpf/20250610215221.846484-1-eddyz87@gmail.com/
v1 -> v2:
- added code to visit /boot/config-$(uname -r) (Yafang, Andrii)
- in case if config can't be read, print a warning and disable
  unprivileged tests execution.

[1] https://lore.kernel.org/bpf/20231025031144.5508-1-laoar.shao@gmail.com/

Eduard Zingerman (1):
  selftests/bpf: more precise cpu_mitigations state detection

 tools/testing/selftests/bpf/unpriv_helpers.c | 93 +++++++++++++++++++-
 1 file changed, 90 insertions(+), 3 deletions(-)

-- 
2.47.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH bpf-next v3 1/1] selftests/bpf: more precise cpu_mitigations state detection
  2025-06-17  0:57 [PATCH bpf-next v3 0/1] selftests/bpf: more precise cpu_mitigations state detection Eduard Zingerman
@ 2025-06-17  0:57 ` Eduard Zingerman
  2025-06-17 20:30 ` [PATCH bpf-next v3 0/1] " patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: Eduard Zingerman @ 2025-06-17  0:57 UTC (permalink / raw)
  To: bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87,
	laoar.shao, mykyta.yatsenko5

test_progs and test_verifier binaries execute unpriv tests under the
following conditions:
- unpriv BPF is enabled;
- CPU mitigations are enabled (see [1] for details).

The detection of the "mitigations enabled" state is performed by
unpriv_helpers.c:get_mitigations_off() via inspecting kernel boot
command line, looking for a parameter "mitigations=off".

Such detection scheme won't work for certain configurations,
e.g. when CONFIG_CPU_MITIGATIONS is disabled and boot parameter is
not supplied.

Miss-detection leads to test_progs executing tests meant to be run
only with mitigations enabled, e.g.
verifier_and.c:known_subreg_with_unknown_reg(), and reporting false
failures.

Internally, verifier sets bpf_verifier_env->bypass_spec_{v1,v4}
basing on the value returned by kernel/cpu.c:cpu_mitigations_off().
This function is backed by a variable kernel/cpu.c:cpu_mitigations.

This state is not fully introspect-able via sysfs. The closest proxy
is /sys/devices/system/cpu/vulnerabilities/spectre_v1, but it reports
"vulnerable" state only if mitigations are disabled *and* current cpu
is vulnerable, while verifier does not check cpu state.

There are only two ways the kernel/cpu.c:cpu_mitigations can be set:
- via boot parameter;
- via CONFIG_CPU_MITIGATIONS option.

This commit updates unpriv_helpers.c:get_mitigations_off() to scan
/boot/config-$(uname -r) and /proc/config.gz for
CONFIG_CPU_MITIGATIONS value in addition to boot command line check.

Tested using the following configurations:
- mitigations enabled (unpriv tests are enabled)
- mitigations disabled via boot cmdline (unpriv tests skipped)
- mitigations disabled via CONFIG_CPU_MITIGATIONS
  (unpriv tests skipped)

[1] https://lore.kernel.org/bpf/20231025031144.5508-1-laoar.shao@gmail.com/

Reported-by: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 tools/testing/selftests/bpf/unpriv_helpers.c | 93 +++++++++++++++++++-
 1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/bpf/unpriv_helpers.c b/tools/testing/selftests/bpf/unpriv_helpers.c
index 220f6a963813..3aa9ee80a55e 100644
--- a/tools/testing/selftests/bpf/unpriv_helpers.c
+++ b/tools/testing/selftests/bpf/unpriv_helpers.c
@@ -1,15 +1,75 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/utsname.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <zlib.h>
 
 #include "unpriv_helpers.h"
 
-static bool get_mitigations_off(void)
+static gzFile open_config(void)
+{
+	struct utsname uts;
+	char buf[PATH_MAX];
+	gzFile config;
+
+	if (uname(&uts)) {
+		perror("uname");
+		goto config_gz;
+	}
+
+	snprintf(buf, sizeof(buf), "/boot/config-%s", uts.release);
+	config = gzopen(buf, "rb");
+	if (config)
+		return config;
+	fprintf(stderr, "gzopen %s: %s\n", buf, strerror(errno));
+
+config_gz:
+	config = gzopen("/proc/config.gz", "rb");
+	if (!config)
+		perror("gzopen /proc/config.gz");
+	return config;
+}
+
+static int config_contains(const char *pat)
+{
+	const char *msg;
+	char buf[1024];
+	gzFile config;
+	int n, err;
+
+	config = open_config();
+	if (!config)
+		return -1;
+
+	for (;;) {
+		if (!gzgets(config, buf, sizeof(buf))) {
+			msg = gzerror(config, &err);
+			if (err == Z_ERRNO)
+				perror("gzgets /proc/config.gz");
+			else if (err != Z_OK)
+				fprintf(stderr, "gzgets /proc/config.gz: %s", msg);
+			gzclose(config);
+			return -1;
+		}
+		n = strlen(buf);
+		if (buf[n - 1] == '\n')
+			buf[n - 1] = 0;
+		if (strcmp(buf, pat) == 0) {
+			gzclose(config);
+			return 1;
+		}
+	}
+	gzclose(config);
+	return 0;
+}
+
+static bool cmdline_contains(const char *pat)
 {
 	char cmdline[4096], *c;
 	int fd, ret = false;
@@ -27,7 +87,7 @@ static bool get_mitigations_off(void)
 
 	cmdline[sizeof(cmdline) - 1] = '\0';
 	for (c = strtok(cmdline, " \n"); c; c = strtok(NULL, " \n")) {
-		if (strncmp(c, "mitigations=off", strlen(c)))
+		if (strncmp(c, pat, strlen(c)))
 			continue;
 		ret = true;
 		break;
@@ -37,8 +97,21 @@ static bool get_mitigations_off(void)
 	return ret;
 }
 
+static int get_mitigations_off(void)
+{
+	int enabled_in_config;
+
+	if (cmdline_contains("mitigations=off"))
+		return 1;
+	enabled_in_config = config_contains("CONFIG_CPU_MITIGATIONS=y");
+	if (enabled_in_config < 0)
+		return -1;
+	return !enabled_in_config;
+}
+
 bool get_unpriv_disabled(void)
 {
+	int mitigations_off;
 	bool disabled;
 	char buf[2];
 	FILE *fd;
@@ -52,5 +125,19 @@ bool get_unpriv_disabled(void)
 		disabled = true;
 	}
 
-	return disabled ? true : get_mitigations_off();
+	if (disabled)
+		return true;
+
+	/*
+	 * Some unpriv tests rely on spectre mitigations being on.
+	 * If mitigations are off or status can't be determined
+	 * assume that unpriv tests are disabled.
+	 */
+	mitigations_off = get_mitigations_off();
+	if (mitigations_off < 0) {
+		fprintf(stderr,
+			"Can't determine if mitigations are enabled, disabling unpriv tests.");
+		return true;
+	}
+	return mitigations_off;
 }
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf-next v3 0/1] selftests/bpf: more precise cpu_mitigations state detection
  2025-06-17  0:57 [PATCH bpf-next v3 0/1] selftests/bpf: more precise cpu_mitigations state detection Eduard Zingerman
  2025-06-17  0:57 ` [PATCH bpf-next v3 1/1] " Eduard Zingerman
@ 2025-06-17 20:30 ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-06-17 20:30 UTC (permalink / raw)
  To: Eduard Zingerman
  Cc: bpf, ast, andrii, daniel, martin.lau, kernel-team, yonghong.song,
	laoar.shao, mykyta.yatsenko5

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:

On Mon, 16 Jun 2025 17:57:09 -0700 you wrote:
> If kernel executing selftests is configured with spectre mitigations
> disabled, verification of unprivileged BPF won't emulate speculative
> branches.
> 
> A number of selftests relies on speculative branches being visited.
> In discussion [1] it was decided not to add additional tests
> classification, but to execute unprivileged tests only when
> mitigations are enabled.
> 
> [...]

Here is the summary with links:
  - [bpf-next,v3,1/1] selftests/bpf: more precise cpu_mitigations state detection
    https://git.kernel.org/bpf/bpf-next/c/fc2915bb8bfc

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-06-17 20:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-17  0:57 [PATCH bpf-next v3 0/1] selftests/bpf: more precise cpu_mitigations state detection Eduard Zingerman
2025-06-17  0:57 ` [PATCH bpf-next v3 1/1] " Eduard Zingerman
2025-06-17 20:30 ` [PATCH bpf-next v3 0/1] " patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).