File Index
Files and directories
Sign in
FILE

unpriv_helpers.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/unpriv_helpers.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2
  3#include <errno.h>
  4#include <limits.h>
  5#include <stdbool.h>
  6#include <stdlib.h>
  7#include <stdio.h>
  8#include <string.h>
  9#include <sys/utsname.h>
 10#include <unistd.h>
 11#include <fcntl.h>
 12#include <zlib.h>
 13
 14#include "unpriv_helpers.h"
 15
 16static gzFile open_config(void)
 17{
 18	struct utsname uts;
 19	char buf[PATH_MAX];
 20	gzFile config;
 21
 22	if (uname(&uts)) {
 23		perror("uname");
 24		goto config_gz;
 25	}
 26
 27	snprintf(buf, sizeof(buf), "/boot/config-%s", uts.release);
 28	config = gzopen(buf, "rb");
 29	if (config)
 30		return config;
 31	fprintf(stderr, "gzopen %s: %s\n", buf, strerror(errno));
 32
 33config_gz:
 34	config = gzopen("/proc/config.gz", "rb");
 35	if (!config)
 36		perror("gzopen /proc/config.gz");
 37	return config;
 38}
 39
 40static int config_contains(const char *pat)
 41{
 42	const char *msg;
 43	char buf[1024];
 44	gzFile config;
 45	int n, err;
 46
 47	config = open_config();
 48	if (!config)
 49		return -1;
 50
 51	for (;;) {
 52		if (!gzgets(config, buf, sizeof(buf))) {
 53			msg = gzerror(config, &err);
 54			if (err == Z_ERRNO)
 55				perror("gzgets /proc/config.gz");
 56			else if (err != Z_OK)
 57				fprintf(stderr, "gzgets /proc/config.gz: %s", msg);
 58			gzclose(config);
 59			return -1;
 60		}
 61		n = strlen(buf);
 62		if (buf[n - 1] == '\n')
 63			buf[n - 1] = 0;
 64		if (strcmp(buf, pat) == 0) {
 65			gzclose(config);
 66			return 1;
 67		}
 68	}
 69	gzclose(config);
 70	return 0;
 71}
 72
 73static bool cmdline_contains(const char *pat)
 74{
 75	char cmdline[4096], *c;
 76	int fd, ret = false;
 77
 78	fd = open("/proc/cmdline", O_RDONLY);
 79	if (fd < 0) {
 80		perror("open /proc/cmdline");
 81		return false;
 82	}
 83
 84	if (read(fd, cmdline, sizeof(cmdline) - 1) < 0) {
 85		perror("read /proc/cmdline");
 86		goto out;
 87	}
 88
 89	cmdline[sizeof(cmdline) - 1] = '\0';
 90	for (c = strtok(cmdline, " \n"); c; c = strtok(NULL, " \n")) {
 91		if (strncmp(c, pat, strlen(c)))
 92			continue;
 93		ret = true;
 94		break;
 95	}
 96out:
 97	close(fd);
 98	return ret;
 99}
100
101static int get_mitigations_off(void)
102{
103	int enabled_in_config;
104
105	if (cmdline_contains("mitigations=off"))
106		return 1;
107	enabled_in_config = config_contains("CONFIG_CPU_MITIGATIONS=y");
108	if (enabled_in_config < 0)
109		return -1;
110	return !enabled_in_config;
111}
112
113bool get_unpriv_disabled(void)
114{
115	int mitigations_off;
116	bool disabled;
117	char buf[2];
118	FILE *fd;
119
120	fd = fopen("/proc/sys/" UNPRIV_SYSCTL, "r");
121	if (fd) {
122		disabled = (fgets(buf, 2, fd) == buf && atoi(buf));
123		fclose(fd);
124	} else {
125		perror("fopen /proc/sys/" UNPRIV_SYSCTL);
126		disabled = true;
127	}
128
129	if (disabled)
130		return true;
131
132	/*
133	 * Some unpriv tests rely on spectre mitigations being on.
134	 * If mitigations are off or status can't be determined
135	 * assume that unpriv tests are disabled.
136	 */
137	mitigations_off = get_mitigations_off();
138	if (mitigations_off < 0) {
139		fprintf(stderr,
140			"Can't determine if mitigations are enabled, disabling unpriv tests.");
141		return true;
142	}
143	return mitigations_off;
144}
~/ Read-only file preview.