From: Masami Hiramatsu (Google) <[email protected]>

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.

Fixes: 302db0f5b3d8 ("tracing/probes: Add a function to search a member of a 
struct/union")
Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
---
 kernel/trace/trace_btf.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c
index 00172f301f25..d3ba356d5503 100644
--- a/kernel/trace/trace_btf.c
+++ b/kernel/trace/trace_btf.c
@@ -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 =


Reply via email to