> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index fc08ac6bcdde..49368ee161b1 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
[ ... ]
> +static int btf_get_type_size(const struct btf *btf, __u32 type_id,
> + const struct btf_type **ret_type)
> +{
> + const struct btf_type *t;
> +
> + *ret_type = btf__type_by_id(btf, 0);
> + if (!type_id)
> + return 0;
> + t = btf__type_by_id(btf, type_id);
> + while (t && btf_type_is_modifier(t))
> + t = btf__type_by_id(btf, t->type);
Does this loop need a maximum resolution depth limit?
If a malformed BTF object contains a circular modifier reference
(e.g., typedef A -> const B -> typedef A), could this loop spin
indefinitely and cause a hang?
> + if (!t)
> + return -EINVAL;
> + *ret_type = t;
> + if (btf_is_ptr(t))
> + return sizeof(void *);
Does this correctly calculate the pointer size for cross-architecture
analysis?
Since libbpf is a user-space library that may process BTF blobs from
different architectures (like a 64-bit tool processing a 32-bit BPF
object), will hardcoding sizeof(void *) return the host's pointer size
instead of the target's pointer size?
Would using btf__pointer_size(btf) be more appropriate here?
> + if (btf_is_int(t) || btf_is_any_enum(t) || btf_is_struct(t) ||
> btf_is_union(t))
> + return t->size;
> + return -EINVAL;
> +}
> +
> +bool btf_type_is_traceable_func(const struct btf *btf, const struct btf_type
> *t)
> +{
> + const struct btf_param *args;
> + const struct btf_type *proto;
> + __u32 i, nargs;
> + int ret;
> +
> + proto = btf_type_by_id(btf, t->type);
Could this cause an out-of-bounds read if t is not a function type?
Because the type and size fields share a union in struct btf_type,
passing a type like BTF_KIND_STRUCT causes its size to be misinterpreted
as a type ID.
The internal btf_type_by_id() helper skips bounds checking. If the
interpreted ID exceeds the BTF type array bounds, it might read past the
end of the array and return a garbage pointer, which would then be
dereferenced in the next line.
Should this verify !btf_is_func(t) first, and use the bounds-checked
public API btf__type_by_id() along with a NULL check for proto?
> + if (BTF_INFO_KIND(proto->info) != BTF_KIND_FUNC_PROTO)
> + return false;
[ ... ]
> diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> index 3781c45b46d3..a9845f57e56c 100644
> --- a/tools/lib/bpf/libbpf_internal.h
> +++ b/tools/lib/bpf/libbpf_internal.h
> @@ -250,6 +250,7 @@ const struct btf_type *skip_mods_and_typedefs(const
> struct btf *btf, __u32 id, _
> const struct btf_header *btf_header(const struct btf *btf);
> void btf_set_base_btf(struct btf *btf, const struct btf *base_btf);
> int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32
> **id_map);
> +bool btf_type_is_traceable_func(const struct btf *btf, const struct btf_type
> *t);
---
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/24598000047