tracing/probes: Fix BTF structure member finder
Subsystems (2)
Masami Hiramatsu (Google)
maintainerv3 cover tracing/probes: Fix BTF structure member finder
Hi,
This is the 3rd version of fixes for the BTF structure member finder in trace_btf.c. Sashiko found 2 problems in it during reviewing the wprobe series.[1][2]
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
Here is the previous thread:
https://lore.kernel.org/all/178822361441.115597.11442662641658772793.stgit@devnote2/
This version decouple the indentation cleanup part from [2/3], and add a new cleanup patch[3/3].
Thanks,
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
Masami Hiramatsu (Google) (3):
tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member tracing/probes: Fix BTF kflag check for anonymous struct member access tracing/probes: Fix code indent in get_bitoffset_of_field()
kernel/trace/trace_btf.c | 31 +++++++++++++++++-------------- kernel/trace/trace_btf.h | 3 ++- kernel/trace/trace_probe.c | 15 ++++++++------- 3 files changed, 27 insertions(+), 22 deletions(-)
--
Masami Hiramatsu (Google) <[email protected]>
Masami Hiramatsu (Google)
maintainerPATCH v3 1/3 tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member
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.
---
Changes in v2:
- added tags.
--- kernel/trace/trace_btf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
kernel/trace/trace_btf.c +6 -6
@@ -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 =
[email protected]
AI reviewRe: [PATCH v3 1/3] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 15 lines
From: Masami Hiramatsu (Google) <[email protected]>
btf_find_struct_member()traverses into nested anonymous structures and unions by pushing members with !member->name_off ontoanon_stack. However, it does not consider the unnamed bitfields (e.g.int : 5orunsigned int : 0) which also havemember->name_off== 0.If such an unnamed bitfield is pushed to
anon_stack, thebtf_find_struct_member()return an error even if there are other valid entries inanon_stack.To fix this, only push unnamed struct/union members to
anon_stack. Also move thebtf_type_is_struct()check to the entry of this function because now it is sure only struct/union are pushed toanon_stack.
Quoted 5 lines
Fixes 302db0f5b3d8 ("tracing/probes: Add a function to search a member of a struct/union")Reported-by Sashiko <[email protected]>Signed-off-by Masami Hiramatsu (Google) <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/178827248631.123716.2627172171811720261.stgit@devnote2?part=1
Masami Hiramatsu (Google)
maintainerPATCH v3 2/3 tracing/probes: Fix BTF kflag check for anonymous struct member access
In reply to Masami Hiramatsu (Google)From: Masami Hiramatsu (Google) <[email protected]>
btf_find_struct_member() traverses into nested anonymous structures and unions to find a struct member. However, get_bitoffset_of_field() in trace_probe.c checked btf_type_kflag(type) using the outer parent type instead of the actual anonymous structure/union that directly contains the found member.
If the parent structure and anonymous structure have mismatched kflags (e.g., the parent has kflag=0 while the anonymous structure has kflag=1 because it contains bitfields), the bitfield size encoded in the upper 8 bits of member->offset is erroneously treated as part of the byte/bit offset, corrupting the resolved offset and failing to set last_bitsize. Similarly, btf_find_struct_member() pushed anonymous member offsets onto anon_stack without masking BTF_MEMBER_BIT_OFFSET() when kflag is set.
To fix this problem, update btf_find_struct_member() to return actual containing structure/union type via member_type, use appropriate __btf_member_bit_offset() to get bit offset, and use member_type for btf_type_kflag() in get_bitoffset_of_field().
---
Changes in v3:
- Remove indent cleanup part since that is a cleanup and no need
to be backported.
Changes in v2:
- remove unneeded NULL initializer for mtype, it should be set if btf_find_struct_member() succeeds.
- Add reported-by from Sashiko.
This is separated from wprobe patch series v14.
- https://lore.kernel.org/all/178810003326.64882.5820404025124695636.stgit@devnote2/
--- kernel/trace/trace_btf.c | 19 +++++++++++-------- kernel/trace/trace_btf.h | 3 ++- kernel/trace/trace_probe.c | 5 +++-- 3 files changed, 16 insertions(+), 11 deletions(-)
kernel/trace/trace_btf.c +11 -8
@@ -61,16 +61,17 @@ struct btf_anon_stack {/* * Find a member of data structure/union by name and return it. -* Return NULL if not found, or -EINVAL if parameter is invalid. -* If the member is an member of anonymous union/structure, the offset -* of that anonymous union/structure is stored into @anon_offset. Caller -* can calculate the correct offset from the root data structure by -* adding anon_offset to the member's offset. +* Return NULL if not found, or ERR_PTR(-EINVAL) if parameter is invalid. +* If the member is a member of an anonymous union/structure, the bit offset +* of that anonymous union/structure is stored into @anon_offset. +* If @member_type is non-NULL, the actual containing structure/union type +* of the found member is stored into @member_type. */ const struct btf_member *btf_find_struct_member (struct btf *btf,const struct btf_type *type,const char *member_name, -u32 *anon_offset) +u32 *anon_offset, +const struct btf_type **member_type) {struct btf_anon_stack *anon_stack;const struct btf_member *member;
@@ -94,14 +95,16 @@ const struct btf_member *btf_find_struct_member(struct btf *btf,if (mtype &&btf_type_is_struct (mtype) && top <BTF_ANON_STACK_MAX ) { anon_stack[top].tid = tid; - anon_stack[top++].offset = - cur_offset + member->offset; + anon_stack[top++].offset = cur_offset + +__btf_member_bit_offset (type, member); } }else { name =btf_name_by_offset (btf, member->name_off);if (name && !strcmp (member_name, name)) {if (anon_offset) *anon_offset = cur_offset; +if (member_type) + *member_type = type; goto out; } }
kernel/trace/trace_btf.h +2 -1
@@ -8,4 +8,5 @@ const struct btf_param *btf_get_func_param(const struct btf_type *func_proto,const struct btf_member *btf_find_struct_member (struct btf *btf,const struct btf_type *type,const char *member_name, -u32 *anon_offset); +u32 *anon_offset, +const struct btf_type **member_type);
kernel/trace/trace_probe.c +3 -2
@@ -625,6 +625,7 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty {const struct btf_type *type = *ptype;const struct btf_member *field; +const struct btf_type *mtype;struct btf *btf =ctx_btf (ctx);char *fieldname = *pfieldname;int bitoffs =0 ;
@@ -640,7 +641,7 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty anon_offs =0 ; field =btf_find_struct_member (btf, type, fieldname, - &anon_offs); + &anon_offs, &mtype);if (IS_ERR (field)) {trace_probe_log_err (ctx->offset,BAD_BTF_TID );return PTR_ERR (field);
@@ -653,7 +654,7 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty bitoffs += anon_offs;/* Accumulate the bit-offsets of the dot-connected fields */ -if (btf_type_kflag (type)) { +if (btf_type_kflag (mtype)) { bitoffs +=BTF_MEMBER_BIT_OFFSET (field->offset); ctx->last_bitsize =BTF_MEMBER_BITFIELD_SIZE (field->offset); }else {
[email protected]
AI reviewRe: [PATCH v3 2/3] tracing/probes: Fix BTF kflag check for anonymous struct member access
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 21 lines
From: Masami Hiramatsu (Google) <[email protected]>
btf_find_struct_member()traverses into nested anonymous structures and unions to find a struct member. However,get_bitoffset_of_field()intrace_probe.ccheckedbtf_type_kflag(type)using the outer parent type instead of the actual anonymous structure/union that directly contains the found member.If the parent structure and anonymous structure have mismatched kflags (e.g., the parent has kflag=0 while the anonymous structure has kflag=1 because it contains bitfields), the bitfield size encoded in the upper 8 bits of
member->offsetis erroneously treated as part of the byte/bit offset, corrupting the resolved offset and failing to setlast_bitsize. Similarly,btf_find_struct_member()pushed anonymous member offsets ontoanon_stackwithout maskingBTF_MEMBER_BIT_OFFSET()when kflag is set.To fix this problem, update
btf_find_struct_member()to return actual containing structure/union type viamember_type, use appropriate__btf_member_bit_offset()to get bit offset, and usemember_typeforbtf_type_kflag()inget_bitoffset_of_field().
Quoted 6 lines
Fixes c440adfbe302 ("tracing/probes: Support BTF based data structure field access")Reported-by Sashiko <[email protected]>Assisted-by Antigravity:gemini-3.7-flashSigned-off-by Masami Hiramatsu (Google) <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/178827248631.123716.2627172171811720261.stgit@devnote2?part=2
Re: [PATCH v3 2/3] tracing/probes: Fix BTF kflag check for anonymous struct member access
In reply to Masami Hiramatsu (Google)Quoted 21 lines · On Tue, 1 Sep 2026 23:21:49 +0900 "Masami Hiramatsu (Google)"…
From: Masami Hiramatsu (Google) <[email protected]>
btf_find_struct_member()traverses into nested anonymous structures and unions to find a struct member. However,get_bitoffset_of_field()intrace_probe.ccheckedbtf_type_kflag(type)using the outer parent type instead of the actual anonymous structure/union that directly contains the found member.If the parent structure and anonymous structure have mismatched kflags (e.g., the parent has kflag=0 while the anonymous structure has kflag=1 because it contains bitfields), the bitfield size encoded in the upper 8 bits of
member->offsetis erroneously treated as part of the byte/bit offset, corrupting the resolved offset and failing to setlast_bitsize. Similarly,btf_find_struct_member()pushed anonymous member offsets ontoanon_stackwithout maskingBTF_MEMBER_BIT_OFFSET()when kflag is set.To fix this problem, update
btf_find_struct_member()to return actual containing structure/union type viamember_type, use appropriate__btf_member_bit_offset()to get bit offset, and usemember_typeforbtf_type_kflag()inget_bitoffset_of_field().
Quoted 6 lines
Fixes c440adfbe302 ("tracing/probes: Support BTF based data structure field access")Reported-by Sashiko <[email protected]>Assisted-by Antigravity:gemini-3.7-flashSigned-off-by Masami Hiramatsu (Google) <[email protected]>
-- Steve
Masami Hiramatsu (Google)
maintainerRe: [PATCH v3 2/3] tracing/probes: Fix BTF kflag check for anonymous struct member access
Quoted 24 lines · On Tue, 1 Sep 2026 10:37:25 -0400 Steven Rostedt <[email protected]> wrote:
Quoted 21 lines · On Tue, 1 Sep 2026 23:21:49 +0900 "Masami Hiramatsu (Google)"…
From: Masami Hiramatsu (Google) <[email protected]>
btf_find_struct_member()traverses into nested anonymous structures and unions to find a struct member. However,get_bitoffset_of_field()intrace_probe.ccheckedbtf_type_kflag(type)using the outer parent type instead of the actual anonymous structure/union that directly contains the found member.If the parent structure and anonymous structure have mismatched kflags (e.g., the parent has kflag=0 while the anonymous structure has kflag=1 because it contains bitfields), the bitfield size encoded in the upper 8 bits of
member->offsetis erroneously treated as part of the byte/bit offset, corrupting the resolved offset and failing to setlast_bitsize. Similarly,btf_find_struct_member()pushed anonymous member offsets ontoanon_stackwithout maskingBTF_MEMBER_BIT_OFFSET()when kflag is set.To fix this problem, update
btf_find_struct_member()to return actual containing structure/union type viamember_type, use appropriate__btf_member_bit_offset()to get bit offset, and usemember_typeforbtf_type_kflag()inget_bitoffset_of_field().
Quoted 8 lines
Quoted 6 lines
Fixes c440adfbe302 ("tracing/probes: Support BTF based data structure field access")Reported-by Sashiko <[email protected]>Assisted-by Antigravity:gemini-3.7-flashSigned-off-by Masami Hiramatsu (Google) <[email protected]>Reviewed-by Steven Rostedt <[email protected]>
Thanks! Let me pick those to probes/fixes.
Quoted 2 lines
-- Steve
Signature · 1 line
Masami Hiramatsu (Google) <[email protected]>
Masami Hiramatsu (Google)
maintainerPATCH v3 3/3 tracing/probes: Fix code indent in get_bitoffset_of_field()
In reply to Masami Hiramatsu (Google)From: Masami Hiramatsu (Google) <[email protected]>
Fix code block indentation introduced by commit f21834524025 ("tracing/probes: Support field specifier option for typecast").
--- kernel/trace/trace_probe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
kernel/trace/trace_probe.c +5 -5
@@ -662,11 +662,11 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty ctx->last_bitsize =0 ; } - type =btf_type_skip_modifiers (btf, field->type,NULL ); -if (!type) { -trace_probe_log_err (ctx->offset,BAD_BTF_TID ); -return -EINVAL ; - } + type =btf_type_skip_modifiers (btf, field->type,NULL ); +if (!type) { +trace_probe_log_err (ctx->offset,BAD_BTF_TID ); +return -EINVAL ; + }if (next) ctx->offset += next - fieldname;
[email protected]
AI reviewRe: [PATCH v3 3/3] tracing/probes: Fix code indent in get_bitoffset_of_field()
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 6 lines
From: Masami Hiramatsu (Google) <[email protected]>
Fix code block indentation introduced by commit
f21834524025("tracing/probes: Support field specifier option for typecast").Signed-off-by Masami Hiramatsu (Google) <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/178827248631.123716.2627172171811720261.stgit@devnote2?part=3
Re: [PATCH v3 3/3] tracing/probes: Fix code indent in get_bitoffset_of_field()
In reply to Masami Hiramatsu (Google)Quoted 6 lines · On Tue, 1 Sep 2026 23:22:00 +0900 "Masami Hiramatsu (Google)"…
From: Masami Hiramatsu (Google) <[email protected]>
Fix code block indentation introduced by commit
f21834524025("tracing/probes: Support field specifier option for typecast").Signed-off-by Masami Hiramatsu (Google) <[email protected]>
-- Steve