diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2026-10-02 12:47:04 +0000 |
|---|---|---|
| committer | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-10-03 16:08:17 +0200 |
| commit | bed1986a1932942e9db17fbdb2a19d0c4160a1f5 (patch) | |
| tree | 0a53b5efad4ba264aa687a41b0edb2b912a35559 /kernel | |
| parent | b233f937b98f8e5c88e2978ef36321f888076274 (diff) | |
| download | linux-bed1986a1932942e9db17fbdb2a19d0c4160a1f5.tar.gz linux-bed1986a1932942e9db17fbdb2a19d0c4160a1f5.zip | |
bpf: Allow names of Rust types and functions in BTF
Names of types and functions in BTF that LLVM makes for a Rust program
are not C identifiers:
[69] STRUCT 'NonNull<str>' size=16 vlen=1
[147] FUNC 'write_fmt<scx_cosmos::BpfStream>' type_id=146
and the kernel rejects such BTF with "Invalid name". scx_simple and
scx_cosmos schedulers written in Rust have them in STRUCT, FWD and FUNC,
made of letters, digits and " #&()*,:;<>[]{}", 430 characters at most.
Allow any printable character in btf_name_valid_identifier(), like it's
done for DATASEC. It checks names of types, functions, members,
enumerators, variables and arguments, so all of them can have such
characters now. The limit of KSYM_NAME_LEN stays.
The name of FUNC is a part of the name of the program in kallsyms, where
a space would break the parsers. Replace what is not a character of
an identifier with '_' there.
Tests in prog_tests/btf.c expect "Invalid name" for names with '!' and
'*', which are valid now. Put a character that is not printable there.
The type name '?foo' is expected to load.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20261002124714.180012-6-alexei.starovoitov@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/btf.c | 15 | ||||
| -rw-r--r-- | kernel/bpf/core.c | 5 |
2 files changed, 8 insertions, 12 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 8cc17a1cd25c..d27af5d8e495 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -901,16 +901,6 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset) return offset < btf->hdr.str_len; } -static bool __btf_name_char_ok(char c, bool first) -{ - if ((first ? !isalpha(c) : - !isalnum(c)) && - c != '_' && - c != '.') - return false; - return true; -} - const char *btf_str_by_offset(const struct btf *btf, u32 offset) { while (offset < btf->start_str_off) @@ -923,20 +913,21 @@ const char *btf_str_by_offset(const struct btf *btf, u32 offset) return NULL; } +/* Names in BTF of Rust are not C identifiers. Allow any printable character */ static bool btf_name_valid_identifier(const struct btf *btf, u32 offset) { /* offset must be valid */ const char *src = btf_str_by_offset(btf, offset); const char *src_limit; - if (!__btf_name_char_ok(*src, true)) + if (!isprint(*src)) return false; /* set a limit on identifier length */ src_limit = src + KSYM_NAME_LEN; src++; while (*src && src < src_limit) { - if (!__btf_name_char_ok(*src, false)) + if (!isprint(*src)) return false; src++; } diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 92a87c73aa44..05c89396119a 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -18,6 +18,7 @@ */ #include <uapi/linux/btf.h> +#include <linux/ctype.h> #include <linux/filter.h> #include <linux/sched/signal.h> #include <linux/skbuff.h> @@ -589,6 +590,10 @@ bpf_prog_ksym_set_name(struct bpf_prog *prog) prog->aux->func_info[prog->aux->func_idx].type_id); func_name = btf_name_by_offset(prog->aux->btf, type->name_off); snprintf(sym, (size_t)(end - sym), "_%s", func_name); + /* the name of a function of Rust is not an identifier */ + for (; *sym; sym++) + if (!isalnum(*sym) && *sym != '_' && *sym != '.') + *sym = '_'; return; } |
