mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
selftests/bpf: Add test for showing a void BTF type
Extend the snprintf_btf test with type_ids from the vmlinux BTF that used to NULL-deref in the BTF show path: a "const void", checked to render the "<unsupported kind:0>" placeholder, and a BTF_KIND_VAR, checked to resolve and render without error. The program renders from its own buffer and the test picks a VAR whose resolved type fits it, so the render stays in bounds. Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://lore.kernel.org/r/20260901104924.346187-6-jiayuan.chen@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
6265b44f2c
commit
1ae6aa6195
|
|
@ -1,7 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <test_progs.h>
|
||||
#include <linux/btf.h>
|
||||
#include <bpf/btf.h>
|
||||
#include "netif_receive_skb.skel.h"
|
||||
#include "snprintf_btf_void.skel.h"
|
||||
|
||||
/* Demonstrate that bpf_snprintf_btf succeeds and that various data types
|
||||
* are formatted correctly.
|
||||
|
|
@ -58,3 +60,80 @@ void serial_test_snprintf_btf(void)
|
|||
cleanup:
|
||||
netif_receive_skb__destroy(skel);
|
||||
}
|
||||
|
||||
/*
|
||||
* bpf_snprintf_btf() renders a type_id taken straight from the vmlinux BTF.
|
||||
* Two such type_ids used to NULL-deref in the BTF show path:
|
||||
* - a "const void" (a modifier resolving to void) in btf_modifier_show()
|
||||
* - a BTF_KIND_VAR in btf_var_show() (base BTF has no resolved_ids)
|
||||
* A fixed kernel renders both without crashing.
|
||||
*/
|
||||
static long run(struct snprintf_btf_void *skel, __u32 type_id)
|
||||
{
|
||||
LIBBPF_OPTS(bpf_test_run_opts, topts);
|
||||
char ctx[8] = {};
|
||||
|
||||
skel->bss->type_id = type_id;
|
||||
topts.ctx_in = ctx;
|
||||
topts.ctx_size_in = sizeof(ctx);
|
||||
if (!ASSERT_OK(bpf_prog_test_run_opts(bpf_program__fd(skel->progs.dump_type),
|
||||
&topts), "test_run"))
|
||||
return -1;
|
||||
return skel->bss->ret;
|
||||
}
|
||||
|
||||
void test_snprintf_btf_void(void)
|
||||
{
|
||||
const struct btf_type *t;
|
||||
struct snprintf_btf_void *skel;
|
||||
int i, n, cv = 0, var = 0;
|
||||
struct btf *btf;
|
||||
|
||||
btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
|
||||
if (!btf) {
|
||||
test__skip();
|
||||
return;
|
||||
}
|
||||
|
||||
skel = snprintf_btf_void__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
|
||||
goto out_btf;
|
||||
|
||||
n = btf__type_cnt(btf);
|
||||
for (i = 1; i < n && !(cv && var); i++) {
|
||||
t = btf__type_by_id(btf, i);
|
||||
if (!cv && btf_kind(t) == BTF_KIND_CONST && t->type == 0)
|
||||
cv = i;
|
||||
/* Pick a VAR small enough to render from the program's buffer. */
|
||||
if (!var && btf_kind(t) == BTF_KIND_VAR) {
|
||||
long sz = btf__resolve_size(btf, t->type);
|
||||
|
||||
if (sz > 0 && sz <= (long)sizeof(skel->bss->obj))
|
||||
var = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* "const void" renders the "<unsupported kind:0>" placeholder. */
|
||||
if (test__start_subtest("const_void")) {
|
||||
if (cv) {
|
||||
ASSERT_EQ(run(skel, cv),
|
||||
sizeof("<unsupported kind:0>") - 1, "ret");
|
||||
ASSERT_STREQ(skel->bss->out, "<unsupported kind:0>",
|
||||
"placeholder");
|
||||
} else {
|
||||
test__skip();
|
||||
}
|
||||
}
|
||||
|
||||
/* A BTF_KIND_VAR must resolve and render without error. */
|
||||
if (test__start_subtest("var")) {
|
||||
if (var)
|
||||
ASSERT_GT(run(skel, var), 0, "ret");
|
||||
else
|
||||
test__skip();
|
||||
}
|
||||
|
||||
snprintf_btf_void__destroy(skel);
|
||||
out_btf:
|
||||
btf__free(btf);
|
||||
}
|
||||
|
|
|
|||
24
tools/testing/selftests/bpf/progs/snprintf_btf_void.c
Normal file
24
tools/testing/selftests/bpf/progs/snprintf_btf_void.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "btf_ptr.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
__u32 type_id;
|
||||
/* A buffer we own to render the selected type from, kept in bounds. */
|
||||
char obj[256];
|
||||
char out[64];
|
||||
long ret;
|
||||
|
||||
SEC("raw_tp/sys_enter")
|
||||
int dump_type(void *ctx)
|
||||
{
|
||||
struct btf_ptr ptr = {
|
||||
.ptr = obj,
|
||||
.type_id = type_id,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
ret = bpf_snprintf_btf(out, sizeof(out), &ptr, sizeof(ptr), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
Loading…
Reference in New Issue
Block a user