* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-02 11:07 [PATCH v4] btf: reject to register duplicated kfunc Song Chen
@ 2026-06-02 11:23 ` sashiko-bot
2026-06-02 11:34 ` Kaitao Cheng
2026-06-02 17:13 ` Yonghong Song
2 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-02 11:23 UTC (permalink / raw)
To: Song Chen; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Kfunc registration incorrectly fails if the kfunc name matches ANY internal or static function in vmlinux or loaded modules, introducing load-order dependencies.
--
commit 8a8189baf0633350e5ca2b793c2340e48f4787df
Author: Song Chen <chensong_2000@126.com>
btf: reject to register duplicated kfunc
This commit attempts to prevent duplicate BPF kfunc registrations by searching
for existing kfunc names in vmlinux and other modules' BTF data during kfunc
registration.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index a62d785812076..ad6b925125dee 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -8684,6 +8684,41 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name,
> return 0;
> }
>
> +static int btf_check_kfunc_name(struct btf *btf, const char *func_name, u32 kind)
> +{
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + struct btf_module *btf_mod, *tmp;
> +#endif
> + s32 id;
> +
> + if (!btf_is_module(btf))
> + return 0;
[Severity: High]
Does this bypass collision checks for built-in vmlinux kfuncs? It looks like
this might fail to catch intra-kernel name collisions.
> +
> + id = btf_find_by_name_kind(bpf_get_btf_vmlinux(), func_name, kind);
[Severity: High]
Since modern kernels generate BTF for all global and static functions, does
btf_find_by_name_kind() with BTF_KIND_FUNC search the entire BTF data rather
than just registered kfuncs?
Will this incorrectly reject a valid kfunc registration if its name happens
to match any unrelated static or internal function anywhere in vmlinux?
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in vmlinux.\n",
> + func_name, id);
> + return -EINVAL;
> + }
> +
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + mutex_lock(&btf_module_mutex);
> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
> + if (btf_mod->btf == btf)
> + continue;
[Severity: High]
Are we skipping collision detection within the module's own BTF here?
> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
[Severity: High]
Can this create unpredictable load-order dependencies between unrelated
modules?
If module A has a static function named "foo", and module B registers a
kfunc named "foo", it appears B will fail to load if A is already loaded,
but will succeed if B is loaded first. Should this code check against actually
registered kfunc sets rather than all functions in every module's BTF?
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in module %s.\n",
> + func_name, id, btf_mod->module->name);
> + mutex_unlock(&btf_module_mutex);
> + return -EINVAL;
> + }
> + }
> + mutex_unlock(&btf_module_mutex);
> +#endif
> + return 0;
> +}
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260602110710.19642-1-chensong_2000@126.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-02 11:07 [PATCH v4] btf: reject to register duplicated kfunc Song Chen
2026-06-02 11:23 ` sashiko-bot
@ 2026-06-02 11:34 ` Kaitao Cheng
2026-06-02 17:13 ` Yonghong Song
2 siblings, 0 replies; 7+ messages in thread
From: Kaitao Cheng @ 2026-06-02 11:34 UTC (permalink / raw)
To: Song Chen
Cc: bpf, ast, alexei.starovoitov, daniel, andrii, eddyz87, song,
yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa,
linux-kernel, martin.lau
在 2026/6/2 19:07, Song Chen 写道:
> I had an ebpf program which calls a kfunc defined and
> implemented in one of my kernel modules, it was working
> fine in 6.16, but was rejected to run by libbpf in 6.19,
> the error message was:
>
> libbpf: extern (func ksym) 'bpf_strstr': func_proto [5]
> incompatible with vmlinux [94389]
>
> 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
> both btf_vmlinux and btf_modules list 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.
>
> Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Suggested-by: Kaitao Cheng <kaitao.cheng@linux.dev>
> Reviewed-by: Yonghong Song <yonghong.song@linux.dev>
> Signed-off-by: Song Chen <chensong_2000@126.com>
>
> ---
> changelog:
> v1 --- v2:
> libbpf has already specified which module this kfunc belongs to as
> ebpf code onwer's expectation, then verifier uses
> find_kallsyms_symbol_value to search kfunc's addr.
>
> v2 --- v3:
> After v2, I tried a new idea of introducing a namespace in libbpf
> to specify kfunc owner in an ebpf program suggested by Kaitao Cheng,
> please see [1]. Alex suggested to go back to report an error during
> kmod load on conflicting kfunc name for now. What's more, v2 only
> searched bpf_vmlinux, v3 also traverses btf_modules list.
>
> v3 --- v4
> Fixed some coding style problems suggested from Kaitao Cheng.
> ---
> kernel/bpf/btf.c | 38 +++++++++++++++++++++++++++++++++++++-
> 1 file changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 4872d2a6c42d..fe1612677a4a 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -8618,6 +8618,41 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name,
> return 0;
> }
>
> +static int btf_check_kfunc_name(struct btf *btf, const char *func_name, u32 kind)
> +{
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + struct btf_module *btf_mod, *tmp;
> +#endif
> + s32 id;
> +
> + if (!btf_is_module(btf))
> + return 0;
> +
> + id = btf_find_by_name_kind(bpf_get_btf_vmlinux(), func_name, kind);
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in vmlinux.\n",
> + func_name, id);
> + return -EINVAL;
> + }
> +
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + mutex_lock(&btf_module_mutex);
> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
> + if (btf_mod->btf == btf)
> + continue;
> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in module %s.\n",
> + func_name, id, btf_mod->module->name);
> + mutex_unlock(&btf_module_mutex);
> + return -EINVAL;
> + }
> + }
> + mutex_unlock(&btf_module_mutex);
> +#endif
> + return 0;
> +}
> +
> static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
> {
> const struct btf_type *func;
> @@ -8631,7 +8666,8 @@ static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
>
> /* sanity check kfunc name */
> func_name = btf_name_by_offset(btf, func->name_off);
> - if (!func_name || !func_name[0])
> + if (!func_name || !func_name[0] ||
> + btf_check_kfunc_name(btf, func_name, BTF_INFO_KIND(func->info)))
> return -EINVAL;
>
> func = btf_type_by_id(btf, func->type);
Reviewed-by: Kaitao Cheng <chengkaitao@kylinos.cn>
--
Thanks
Kaitao Cheng
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-02 11:07 [PATCH v4] btf: reject to register duplicated kfunc Song Chen
2026-06-02 11:23 ` sashiko-bot
2026-06-02 11:34 ` Kaitao Cheng
@ 2026-06-02 17:13 ` Yonghong Song
2026-06-03 2:18 ` Leon Hwang
2026-06-03 9:11 ` Song Chen
2 siblings, 2 replies; 7+ messages in thread
From: Yonghong Song @ 2026-06-02 17:13 UTC (permalink / raw)
To: Song Chen, martin.lau, ast, alexei.starovoitov, daniel, andrii,
eddyz87, song, john.fastabend, kpsingh, sdf, haoluo, jolsa,
kaitao.cheng
Cc: bpf, linux-kernel
On 6/2/26 4:07 AM, Song Chen wrote:
> I had an ebpf program which calls a kfunc defined and
> implemented in one of my kernel modules, it was working
> fine in 6.16, but was rejected to run by libbpf in 6.19,
> the error message was:
>
> libbpf: extern (func ksym) 'bpf_strstr': func_proto [5]
> incompatible with vmlinux [94389]
>
> 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
> both btf_vmlinux and btf_modules list 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.
>
> Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Suggested-by: Kaitao Cheng <kaitao.cheng@linux.dev>
> Reviewed-by: Yonghong Song <yonghong.song@linux.dev>
> Signed-off-by: Song Chen <chensong_2000@126.com>
The subject can be [PATCH bpf v4] bpf: Reject to register duplicated kfunc
>
> ---
> changelog:
> v1 --- v2:
> libbpf has already specified which module this kfunc belongs to as
> ebpf code onwer's expectation, then verifier uses
> find_kallsyms_symbol_value to search kfunc's addr.
>
> v2 --- v3:
> After v2, I tried a new idea of introducing a namespace in libbpf
> to specify kfunc owner in an ebpf program suggested by Kaitao Cheng,
> please see [1]. Alex suggested to go back to report an error during
> kmod load on conflicting kfunc name for now. What's more, v2 only
> searched bpf_vmlinux, v3 also traverses btf_modules list.
>
> v3 --- v4
> Fixed some coding style problems suggested from Kaitao Cheng.
> ---
> kernel/bpf/btf.c | 38 +++++++++++++++++++++++++++++++++++++-
> 1 file changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 4872d2a6c42d..fe1612677a4a 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -8618,6 +8618,41 @@ static int btf_check_iter_kfuncs(struct btf *btf, const char *func_name,
> return 0;
> }
>
> +static int btf_check_kfunc_name(struct btf *btf, const char *func_name, u32 kind)
> +{
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + struct btf_module *btf_mod, *tmp;
> +#endif
> + s32 id;
s32 err = 0, id;
> +
> + if (!btf_is_module(btf))
> + return 0;
> +
> + id = btf_find_by_name_kind(bpf_get_btf_vmlinux(), func_name, kind);
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in vmlinux.\n",
> + func_name, id);
> + return -EINVAL;
> + }
> +
> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> + mutex_lock(&btf_module_mutex);
> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
> + if (btf_mod->btf == btf)
> + continue;
> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
> + if (id >= 0) {
> + pr_err("kfunc %s (id: %d) is already present in module %s.\n",
> + func_name, id, btf_mod->module->name);
> + mutex_unlock(&btf_module_mutex);
> + return -EINVAL;
Let us avoid the above mutex_unlock and 'return -EINVAL', just do
err = -EINVAL;
break;
> + }
> + }
> + mutex_unlock(&btf_module_mutex);
> +#endif
> + return 0;
return err;
> +}
> +
> static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
> {
> const struct btf_type *func;
> @@ -8631,7 +8666,8 @@ static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
>
> /* sanity check kfunc name */
> func_name = btf_name_by_offset(btf, func->name_off);
> - if (!func_name || !func_name[0])
> + if (!func_name || !func_name[0] ||
> + btf_check_kfunc_name(btf, func_name, BTF_INFO_KIND(func->info)))
format issue:
if (!func_name || !func_name[0] ||
btf_check_kfunc_name(btf, func_name, BTF_INFO_KIND(func->info)))
...
> return -EINVAL;
>
> func = btf_type_by_id(btf, func->type);
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-02 17:13 ` Yonghong Song
@ 2026-06-03 2:18 ` Leon Hwang
2026-06-03 9:15 ` Song Chen
2026-06-03 9:11 ` Song Chen
1 sibling, 1 reply; 7+ messages in thread
From: Leon Hwang @ 2026-06-03 2:18 UTC (permalink / raw)
To: Yonghong Song, Song Chen, martin.lau, ast, alexei.starovoitov,
daniel, andrii, eddyz87, song, john.fastabend, kpsingh, sdf,
haoluo, jolsa, kaitao.cheng
Cc: bpf, linux-kernel
On 3/6/26 01:13, Yonghong Song wrote:
>
>
> On 6/2/26 4:07 AM, Song Chen wrote:
[...]
>> +
>> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
>> + mutex_lock(&btf_module_mutex);
>> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
>> + if (btf_mod->btf == btf)
>> + continue;
>> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
>> + if (id >= 0) {
>> + pr_err("kfunc %s (id: %d) is already present in module
>> %s.\n",
>> + func_name, id, btf_mod->module->name);
>> + mutex_unlock(&btf_module_mutex);
>> + return -EINVAL;
>
> Let us avoid the above mutex_unlock and 'return -EINVAL', just do
> err = -EINVAL;
> break;
>
Better to use guard(mutex)(&btf_module_mutex)?
Thanks,
Leon
>> [...]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-03 2:18 ` Leon Hwang
@ 2026-06-03 9:15 ` Song Chen
0 siblings, 0 replies; 7+ messages in thread
From: Song Chen @ 2026-06-03 9:15 UTC (permalink / raw)
To: Leon Hwang, Yonghong Song, martin.lau, ast, alexei.starovoitov,
daniel, andrii, eddyz87, song, john.fastabend, kpsingh, sdf,
haoluo, jolsa, kaitao.cheng
Cc: bpf, linux-kernel
Hi,
在 2026/6/3 10:18, Leon Hwang 写道:
> On 3/6/26 01:13, Yonghong Song wrote:
>>
>>
>> On 6/2/26 4:07 AM, Song Chen wrote:
> [...]
>>> +
>>> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
>>> + mutex_lock(&btf_module_mutex);
>>> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
>>> + if (btf_mod->btf == btf)
>>> + continue;
>>> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
>>> + if (id >= 0) {
>>> + pr_err("kfunc %s (id: %d) is already present in module
>>> %s.\n",
>>> + func_name, id, btf_mod->module->name);
>>> + mutex_unlock(&btf_module_mutex);
>>> + return -EINVAL;
>>
>> Let us avoid the above mutex_unlock and 'return -EINVAL', just do
>> err = -EINVAL;
>> break;
>>
>
> Better to use guard(mutex)(&btf_module_mutex)?
>
This is the first time i used guard and it's awesome. I have tested in
my code and will send a new patch later, many thanks.
> Thanks,
> Leon
>
>>> [...]
Song
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4] btf: reject to register duplicated kfunc
2026-06-02 17:13 ` Yonghong Song
2026-06-03 2:18 ` Leon Hwang
@ 2026-06-03 9:11 ` Song Chen
1 sibling, 0 replies; 7+ messages in thread
From: Song Chen @ 2026-06-03 9:11 UTC (permalink / raw)
To: Yonghong Song, martin.lau, ast, alexei.starovoitov, daniel,
andrii, eddyz87, song, john.fastabend, kpsingh, sdf, haoluo,
jolsa, kaitao.cheng
Cc: bpf, linux-kernel
Hi,
在 2026/6/3 01:13, Yonghong Song 写道:
>
>
> On 6/2/26 4:07 AM, Song Chen wrote:
>> I had an ebpf program which calls a kfunc defined and
>> implemented in one of my kernel modules, it was working
>> fine in 6.16, but was rejected to run by libbpf in 6.19,
>> the error message was:
>>
>> libbpf: extern (func ksym) 'bpf_strstr': func_proto [5]
>> incompatible with vmlinux [94389]
>>
>> 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
>> both btf_vmlinux and btf_modules list 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.
>>
>> Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
>> Suggested-by: Kaitao Cheng <kaitao.cheng@linux.dev>
>> Reviewed-by: Yonghong Song <yonghong.song@linux.dev>
>> Signed-off-by: Song Chen <chensong_2000@126.com>
>
> The subject can be [PATCH bpf v4] bpf: Reject to register duplicated kfunc
>
>>
>> ---
>> changelog:
>> v1 --- v2:
>> libbpf has already specified which module this kfunc belongs to as
>> ebpf code onwer's expectation, then verifier uses
>> find_kallsyms_symbol_value to search kfunc's addr.
>>
>> v2 --- v3:
>> After v2, I tried a new idea of introducing a namespace in libbpf
>> to specify kfunc owner in an ebpf program suggested by Kaitao Cheng,
>> please see [1]. Alex suggested to go back to report an error during
>> kmod load on conflicting kfunc name for now. What's more, v2 only
>> searched bpf_vmlinux, v3 also traverses btf_modules list.
>>
>> v3 --- v4
>> Fixed some coding style problems suggested from Kaitao Cheng.
>> ---
>> kernel/bpf/btf.c | 38 +++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 37 insertions(+), 1 deletion(-)
>>
>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>> index 4872d2a6c42d..fe1612677a4a 100644
>> --- a/kernel/bpf/btf.c
>> +++ b/kernel/bpf/btf.c
>> @@ -8618,6 +8618,41 @@ static int btf_check_iter_kfuncs(struct btf
>> *btf, const char *func_name,
>> return 0;
>> }
>> +static int btf_check_kfunc_name(struct btf *btf, const char
>> *func_name, u32 kind)
>> +{
>> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
>> + struct btf_module *btf_mod, *tmp;
>> +#endif
>> + s32 id;
>
> s32 err = 0, id;
>
>> +
>> + if (!btf_is_module(btf))
>> + return 0;
>> +
>> + id = btf_find_by_name_kind(bpf_get_btf_vmlinux(), func_name, kind);
>> + if (id >= 0) {
>> + pr_err("kfunc %s (id: %d) is already present in vmlinux.\n",
>> + func_name, id);
>> + return -EINVAL;
>> + }
>> +
>> +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
>> + mutex_lock(&btf_module_mutex);
>> + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) {
>> + if (btf_mod->btf == btf)
>> + continue;
>> + id = btf_find_by_name_kind(btf_mod->btf, func_name, kind);
>> + if (id >= 0) {
>> + pr_err("kfunc %s (id: %d) is already present in module
>> %s.\n",
>> + func_name, id, btf_mod->module->name);
>> + mutex_unlock(&btf_module_mutex);
>> + return -EINVAL;
>
> Let us avoid the above mutex_unlock and 'return -EINVAL', just do
> err = -EINVAL;
> break;
>
>> + }
>> + }
>> + mutex_unlock(&btf_module_mutex);
>> +#endif
>> + return 0;
>
> return err;
>
I will go with guard(mutex), please review my next submit and let me
know if you're ok with it or not. Thanks.
>> +}
>> +
>> static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32
>> func_flags)
>> {
>> const struct btf_type *func;
>> @@ -8631,7 +8666,8 @@ static int btf_check_kfunc_protos(struct btf
>> *btf, u32 func_id, u32 func_flags)
>> /* sanity check kfunc name */
>> func_name = btf_name_by_offset(btf, func->name_off);
>> - if (!func_name || !func_name[0])
>> + if (!func_name || !func_name[0] ||
>> + btf_check_kfunc_name(btf, func_name, BTF_INFO_KIND(func->info)))
>
> format issue:
> if (!func_name || !func_name[0] ||
> btf_check_kfunc_name(btf, func_name, BTF_INFO_KIND(func->info)))
> ...
>
I will fix it with indentation plus space.
>> return -EINVAL;
>> func = btf_type_by_id(btf, func->type);
>
many thanks.
Song
^ permalink raw reply [flat|nested] 7+ messages in thread