mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 17:00:41 -04:00
tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member
btf_find_struct_member() traverses into nested anonymous structures
and unions by pushing members with !member->name_off onto anon_stack.
However, it does not consider the unnamed bitfields (e.g. `int : 5`
or `unsigned int : 0`) which also have member->name_off == 0.
If such an unnamed bitfield is pushed to anon_stack, the
btf_find_struct_member() return an error even if there are other
valid entries in anon_stack.
To fix this, only push unnamed struct/union members to anon_stack.
Also move the btf_type_is_struct() check to the entry of this function
because now it is sure only struct/union are pushed to anon_stack.
Link: https://lore.kernel.org/all/178827249775.123716.7813217688423513612.stgit@devnote2/
Fixes: 302db0f5b3 ("tracing/probes: Add a function to search a member of a struct/union")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260830143859.D56991F00A3D@smtp.kernel.org/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
@@ -74,24 +74,24 @@ const struct btf_member *btf_find_struct_member(struct btf *btf,
|
||||
{
|
||||
struct btf_anon_stack *anon_stack;
|
||||
const struct btf_member *member;
|
||||
const struct btf_type *mtype;
|
||||
u32 tid, cur_offset = 0;
|
||||
const char *name;
|
||||
int i, top = 0;
|
||||
|
||||
if (!btf_type_is_struct(type))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
anon_stack = kzalloc_objs(*anon_stack, BTF_ANON_STACK_MAX);
|
||||
if (!anon_stack)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
retry:
|
||||
if (!btf_type_is_struct(type)) {
|
||||
member = ERR_PTR(-EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for_each_member(i, type, member) {
|
||||
if (!member->name_off) {
|
||||
/* Anonymous union/struct: push it for later use */
|
||||
if (btf_type_skip_modifiers(btf, member->type, &tid) &&
|
||||
mtype = btf_type_skip_modifiers(btf, member->type, &tid);
|
||||
if (mtype && btf_type_is_struct(mtype) &&
|
||||
top < BTF_ANON_STACK_MAX) {
|
||||
anon_stack[top].tid = tid;
|
||||
anon_stack[top++].offset =
|
||||
|
||||
Reference in New Issue
Block a user