On 03/10/2026 20:59, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
> to consider:
> - [High] bpf: kernel panic on NULL pointer dereference in btf_parse_module() 
> error path
> --
> 
> commit 7871f353137bb8eca880dde9f21fa3041a6f681f
> Author: Alan Maguire <[email protected]>
> 
> btf: Relocate and expose module inline BTF
> 
> This commit introduces parsing of module inline BTF data, rebases inline type
> IDs on top of the relocated module BTF, and exposes the result via sysfs.
> Malformed inline BTF is warned about and skipped without preventing normal
> module BTF registration.
> 
>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>> index c535e636d41c1..28b7c9786fdce 100644
>> --- a/kernel/bpf/btf.c
>> +++ b/kernel/bpf/btf.c
> [ ... ]
>> @@ -6954,67 +7076,66 @@ static struct btf *btf_parse_module(const char 
>> *module_name, const void *data,
>>              base_btf = vmlinux_btf;
>>      }
>>  
>> -    btf = kzalloc_obj(*btf, GFP_KERNEL | __GFP_NOWARN);
>> -    if (!btf) {
>> -            err = -ENOMEM;
>> +    btf = btf_parse_split(env, module_name, data, data_size, base_btf);
>> +    if (IS_ERR(btf)) {
>> +            err = PTR_ERR(btf);
>> +            btf = NULL;
>>              goto errout;
>>      }
> [ ... ]
>>  errout:
>> +    kvfree(module_str_map);
>>      btf_verifier_env_free(env);
>> +    btf_free(inline_btf);
>>      if (!IS_ERR(base_btf) && base_btf != vmlinux_btf)
>>              btf_free(base_btf);
>> -    if (btf) {
>> -            kvfree(btf->data);
>> -            kvfree(btf->types);
>> -            kfree(btf);
>> -    }
>> +    btf_free(btf);
> 
> [Severity: High]
> Will this cause a kernel panic if btf_parse_split() fails?
> 
> In the error path above, if btf_parse_split() returns an error, btf is
> explicitly set to NULL and execution jumps to errout. At this point,
> inline_btf is also initialized to NULL.
> 
> The errout path then calls btf_free() unconditionally for both inline_btf
> and btf. Looking at btf_free():
> 
> static void btf_free(struct btf *btf)
> {
>         btf_free_struct_meta_tab(btf);
>         ...
> }
> 
> And btf_free_struct_meta_tab() unconditionally dereferences the pointer:
> 
> static void btf_free_struct_meta_tab(struct btf *btf)
> {
>         struct btf_struct_metas *tab = btf->struct_meta_tab;
>         ...
> }
> 
> Does this result in an immediate NULL pointer dereference when
> btf_free() is called on the NULL btf or inline_btf pointers?
> 
>>      return ERR_PTR(err);
>>  }
> 

we need non-null guards on the btf_free()s alright, good catch.

Reply via email to