Files
linux/tools/testing/selftests/bpf/sysctl_helpers.c
Eduard Zingerman 969fb456ff selftests/bpf: verify kallsyms entries for token-loaded subprograms
Add a test that loads an XDP program with a global subprogram using a
BPF token from a user namespace, then verifies that both the main
program and the subprogram appear in /proc/kallsyms.

This exercises the bpf_prog_kallsyms_add() path for subprograms and
would have caught the missing aux->token copy in bpf_jit_subprogs().

load_kallsyms_local() filters out kallsyms with zero addresses.
For a process with limited capabilities to read kallsym addresses the
following sysctl variables have to be set to zero:
- /proc/sys/kernel/perf_event_paranoid
- /proc/sys/kernel/kptr_restrict
Set these variables using sysctl_set() utility function extracted from
unpriv_bpf_disabled.c to a separate c/header.
Since the test modifies global system state, mark it as serial.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260415-subprog-token-fix-v4-2-9bd000e8b068@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-04-15 16:46:47 -07:00

38 lines
805 B
C

// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "sysctl_helpers.h"
#include "test_progs.h"
int sysctl_set(const char *sysctl_path, char *old_val, const char *new_val)
{
int ret = 0;
FILE *fp;
fp = fopen(sysctl_path, "r+");
if (!fp)
return -errno;
if (old_val && fscanf(fp, "%s", old_val) <= 0) {
ret = -ENOENT;
} else if (!old_val || strcmp(old_val, new_val) != 0) {
fseek(fp, 0, SEEK_SET);
if (fprintf(fp, "%s", new_val) < 0)
ret = -errno;
}
fclose(fp);
return ret;
}
int sysctl_set_or_fail(const char *sysctl_path, char *old_val, const char *new_val)
{
int err;
err = sysctl_set(sysctl_path, old_val, new_val);
if (err)
PRINT_FAIL("failed to set %s to %s: %s\n", sysctl_path, new_val, strerror(-err));
return err;
}