* [PATCH] kernel/bpf/btf.c: reject to register duplicated kfunc @ 2026-01-21 1:51 chensong_2000 2026-01-21 2:16 ` bot+bpf-ci 0 siblings, 1 reply; 3+ messages in thread From: chensong_2000 @ 2026-01-21 1:51 UTC (permalink / raw) To: martin.lau, ast, daniel, andrii, eddyz87, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: bpf, linux-kernel, Song Chen From: Song Chen <chensong_2000@189.cn> I had an ebpf program which calls a kfunc defined and implemented in one of my kernel modules, they were working fine in 6.16, but was broken by libbpf in 6.19, the error message was: libbpf: extern (func ksym) 'bpf_strstr': func_proto [5] incompatible with vmlinux [94389] yes, the reason is there is a new added kfunc in kernel 6.19 which happens to be the same name with my kfunc. However the error message is not obvious enough to address problem immediately. Therefore, this patches searches duplicated kfunc in btf_vmlinux before a kernel module attempts to register kfuncs through register_btf_kfunc_id_set, it prints clear error message and returns error code if same name kfunc has already implemented and registered, then developer knows at the first place. Signed-off-by: Song Chen <chensong_2000@189.cn> --- kernel/bpf/btf.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 0de8fc8a0e0b..1f3879fe163c 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -8498,12 +8498,23 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name, return 0; } -static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags) +static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags, + const struct module *module) { const struct btf_type *func; const char *func_name; int err; + /* check if there is any duplicated kfunc in vmlinux */ + if (module) { + func = btf_type_by_id(btf_vmlinux, func_id); + if (func) { + pr_err("kfunc %s is already present in vmlinux\n", + btf_name_by_offset(btf_vmlinux, func->name_off)); + return -EINVAL; + } + } + /* any kfunc should be FUNC -> FUNC_PROTO */ func = btf_type_by_id(btf, func_id); if (!func || !btf_type_is_func(func)) @@ -8757,7 +8768,7 @@ static int __register_btf_kfunc_id_set(enum btf_kfunc_hook hook, for (i = 0; i < kset->set->cnt; i++) { ret = btf_check_kfunc_protos(btf, btf_relocate_id(btf, kset->set->pairs[i].id), - kset->set->pairs[i].flags); + kset->set->pairs[i].flags, kset->owner); if (ret) goto err_out; } -- 2.43.0 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] kernel/bpf/btf.c: reject to register duplicated kfunc 2026-01-21 1:51 [PATCH] kernel/bpf/btf.c: reject to register duplicated kfunc chensong_2000 @ 2026-01-21 2:16 ` bot+bpf-ci 2026-01-21 7:51 ` Song Chen 0 siblings, 1 reply; 3+ messages in thread From: bot+bpf-ci @ 2026-01-21 2:16 UTC (permalink / raw) To: chensong_2000, martin.lau, ast, daniel, andrii, eddyz87, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: bpf, linux-kernel, chensong_2000, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 2730 bytes --] > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index d10b3404260f..b4ded7669642 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -8615,12 +8615,23 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name, > return 0; > } > > -static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags) > +static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags, > + const struct module *module) > { > const struct btf_type *func; > const char *func_name; > int err; > > + /* check if there is any duplicated kfunc in vmlinux */ > + if (module) { > + func = btf_type_by_id(btf_vmlinux, func_id); The func_id parameter comes from the module's BTF (via btf_relocate_id), but this code looks it up in btf_vmlinux. BTF type IDs are specific to each BTF - vmlinux and modules have independent ID namespaces. Is this lookup correct? btf_type_by_id(btf_vmlinux, func_id) will return whatever type happens to be at that numeric ID in vmlinux, not the type with the same name as the module's kfunc. For example, if the module's kfunc has BTF ID 100, this returns vmlinux type ID 100, which is likely an unrelated struct or typedef. This seems like it would cause false positives - any module kfunc registration would fail if its BTF ID happens to fall within vmlinux's BTF ID range (vmlinux typically has tens of thousands of types). To detect duplicate names, shouldn't this use btf_find_by_name_kind() to search by the function name instead of btf_type_by_id()? > + if (func) { > + pr_err("kfunc %s is already present in vmlinux\n", > + btf_name_by_offset(btf_vmlinux, func->name_off)); Since func is an unrelated vmlinux type (not the module's kfunc), this error message prints the wrong function name - it shows whatever random vmlinux type was found at that ID, not the module's kfunc name. > + return -EINVAL; > + } > + } [ ... ] > @@ -8911,7 +8922,7 @@ static int __register_btf_kfunc_id_set(enum btf_kfunc_hook hook, > > for (i = 0; i < kset->set->cnt; i++) { > ret = btf_check_kfunc_protos(btf, btf_relocate_id(btf, kset->set->pairs[i].id), > - kset->set->pairs[i].flags); > + kset->set->pairs[i].flags, kset->owner); This shows that func_id passed to btf_check_kfunc_protos is from the module's BTF (btf_relocate_id operates on the module's btf), confirming the namespace mismatch when it gets looked up in btf_vmlinux above. > if (ret) > goto err_out; > } --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21194595610 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] kernel/bpf/btf.c: reject to register duplicated kfunc 2026-01-21 2:16 ` bot+bpf-ci @ 2026-01-21 7:51 ` Song Chen 0 siblings, 0 replies; 3+ messages in thread From: Song Chen @ 2026-01-21 7:51 UTC (permalink / raw) To: bot+bpf-ci, martin.lau, ast, daniel, andrii, eddyz87, song, yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa Cc: bpf, linux-kernel, martin.lau, clm, ihor.solodrai hi, 在 2026/1/21 10:16, bot+bpf-ci@kernel.org 写道: >> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> index d10b3404260f..b4ded7669642 100644 >> --- a/kernel/bpf/btf.c >> +++ b/kernel/bpf/btf.c >> @@ -8615,12 +8615,23 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name, >> return 0; >> } >> >> -static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags) >> +static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags, >> + const struct module *module) >> { >> const struct btf_type *func; >> const char *func_name; >> int err; >> >> + /* check if there is any duplicated kfunc in vmlinux */ >> + if (module) { >> + func = btf_type_by_id(btf_vmlinux, func_id); > > The func_id parameter comes from the module's BTF (via btf_relocate_id), > but this code looks it up in btf_vmlinux. BTF type IDs are specific to > each BTF - vmlinux and modules have independent ID namespaces. > > Is this lookup correct? btf_type_by_id(btf_vmlinux, func_id) will return > whatever type happens to be at that numeric ID in vmlinux, not the type > with the same name as the module's kfunc. For example, if the module's > kfunc has BTF ID 100, this returns vmlinux type ID 100, which is likely > an unrelated struct or typedef. > > This seems like it would cause false positives - any module kfunc > registration would fail if its BTF ID happens to fall within vmlinux's > BTF ID range (vmlinux typically has tens of thousands of types). > > To detect duplicate names, shouldn't this use btf_find_by_name_kind() > to search by the function name instead of btf_type_by_id()? The namespace has come up to my mind at the first place, i dumped kfunc info from btf_vmlinux and my module, turned out, they had same btf id: [ 114.348494] Hello, world!, id:150090 [ 114.348499] dump_btf_info, btf name:hello, btf addr:0xffff8bc468c0bb00, nr_types:153081 [ 115.709254] BTF ID 150090: [ 115.709255] name_off: 2480470 [ 115.709259] name: bpf_strstr [ 115.709259] kind: 12 (FUNC) [ 115.709260] type_id: 150066 [ 115.709260] addr: 0xffffffffa93f9f50 [ 115.720383] BTF ID 153075: [ 115.720384] name_off: 2480470 [ 115.720384] name: bpf_strstr [ 115.720385] kind: 12 (FUNC) [ 115.720385] type_id: 153074 [ 115.720385] addr: 0xffffffffa93f9f50 [ 115.720397] dump_btf_info, btf name:vmlinux, btf addr:0xffff8bc446112000, nr_types:153074 [ 117.067793] BTF ID 150090: [ 117.067794] name_off: 2480470 [ 117.067794] name: bpf_strstr [ 117.067795] kind: 12 (FUNC) [ 117.067796] type_id: 150066 [ 117.067796] addr: 0xffffffffa93f9f50 [ 117.078950] bpf_kfunc_example: Module loaded successfully Is this a coincidence? I couldn't help but think btf_id is a global value. If you have been trained with this kind of knowledge, i would appreciate it if you could explain. Nevertheless, btf_find_by_name_kind is a more reasonable way to approach, i will submit v2 to review. many thanks /Song > >> + if (func) { >> + pr_err("kfunc %s is already present in vmlinux\n", >> + btf_name_by_offset(btf_vmlinux, func->name_off)); > > Since func is an unrelated vmlinux type (not the module's kfunc), this > error message prints the wrong function name - it shows whatever random > vmlinux type was found at that ID, not the module's kfunc name. > >> + return -EINVAL; >> + } >> + } > > [ ... ] > >> @@ -8911,7 +8922,7 @@ static int __register_btf_kfunc_id_set(enum btf_kfunc_hook hook, >> >> for (i = 0; i < kset->set->cnt; i++) { >> ret = btf_check_kfunc_protos(btf, btf_relocate_id(btf, kset->set->pairs[i].id), >> - kset->set->pairs[i].flags); >> + kset->set->pairs[i].flags, kset->owner); > > This shows that func_id passed to btf_check_kfunc_protos is from the > module's BTF (btf_relocate_id operates on the module's btf), confirming > the namespace mismatch when it gets looked up in btf_vmlinux above. > >> if (ret) >> goto err_out; >> } > > > --- > AI reviewed your patch. Please fix the bug or email reply why it's not a bug. > See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md > > CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21194595610 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-01-21 7:56 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-01-21 1:51 [PATCH] kernel/bpf/btf.c: reject to register duplicated kfunc chensong_2000 2026-01-21 2:16 ` bot+bpf-ci 2026-01-21 7:51 ` Song Chen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®