* [PATCH v2 0/2] tracing/probes: Fix BTF structure member finder
@ 2026-09-01 0:46 Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 1/2] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access Masami Hiramatsu (Google)
0 siblings, 2 replies; 5+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-09-01 0:46 UTC (permalink / raw)
To: Steven Rostedt, Peter Zijlstra, Ingo Molnar, x86
Cc: Jinchao Wang, Mathieu Desnoyers, Masami Hiramatsu,
Thomas Gleixner, Borislav Petkov, Dave Hansen, H . Peter Anvin,
Alexander Shishkin, Ian Rogers, linux-kernel, linux-trace-kernel,
linux-doc, linux-perf-users
Hi,
This is the 2nd 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/20260822095110.0772E1F000E9@smtp.kernel.org/
[2] https://lore.kernel.org/all/20260830143859.D56991F00A3D@smtp.kernel.org/
Here is the previous thread:
https://lore.kernel.org/all/178818875393.104360.1469039168635349344.stgit@devnote2/
This version added required tags and remove unneeded NULL initializer[2/2]
Thanks,
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
Masami Hiramatsu (Google) (2):
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
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) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member
2026-09-01 0:46 [PATCH v2 0/2] tracing/probes: Fix BTF structure member finder Masami Hiramatsu (Google)
@ 2026-09-01 0:47 ` Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access Masami Hiramatsu (Google)
1 sibling, 0 replies; 5+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-09-01 0:47 UTC (permalink / raw)
To: Steven Rostedt, Peter Zijlstra, Ingo Molnar, x86
Cc: Jinchao Wang, Mathieu Desnoyers, Masami Hiramatsu,
Thomas Gleixner, Borislav Petkov, Dave Hansen, H . Peter Anvin,
Alexander Shishkin, Ian Rogers, linux-kernel, linux-trace-kernel,
linux-doc, linux-perf-users
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
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")
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>
---
Changes in v2:
- added tags.
---
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 =
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access
2026-09-01 0:46 [PATCH v2 0/2] tracing/probes: Fix BTF structure member finder Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 1/2] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Masami Hiramatsu (Google)
@ 2026-09-01 0:47 ` Masami Hiramatsu (Google)
2026-09-01 13:04 ` Steven Rostedt
1 sibling, 1 reply; 5+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-09-01 0:47 UTC (permalink / raw)
To: Steven Rostedt, Peter Zijlstra, Ingo Molnar, x86
Cc: Jinchao Wang, Mathieu Desnoyers, Masami Hiramatsu,
Thomas Gleixner, Borislav Petkov, Dave Hansen, H . Peter Anvin,
Alexander Shishkin, Ian Rogers, linux-kernel, linux-trace-kernel,
linux-doc, linux-perf-users
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
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().
Fixes: c440adfbe302 ("tracing/probes: Support BTF based data structure field access")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260822095110.0772E1F000E9@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.7-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
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 | 15 ++++++++-------
3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c
index d3ba356d5503..ee7a04886bf6 100644
--- a/kernel/trace/trace_btf.c
+++ b/kernel/trace/trace_btf.c
@@ -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;
}
}
diff --git a/kernel/trace/trace_btf.h b/kernel/trace/trace_btf.h
index 4bc44bc261e6..4bd26bceae23 100644
--- a/kernel/trace/trace_btf.h
+++ b/kernel/trace/trace_btf.h
@@ -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);
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index c4163904ba74..908b4b6bc2df 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -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 {
@@ -661,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;
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access
2026-09-01 0:47 ` [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access Masami Hiramatsu (Google)
@ 2026-09-01 13:04 ` Steven Rostedt
2026-09-01 14:00 ` Masami Hiramatsu
0 siblings, 1 reply; 5+ messages in thread
From: Steven Rostedt @ 2026-09-01 13:04 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Peter Zijlstra, Ingo Molnar, x86, Jinchao Wang, Mathieu Desnoyers,
Thomas Gleixner, Borislav Petkov, Dave Hansen, H . Peter Anvin,
Alexander Shishkin, Ian Rogers, linux-kernel, linux-trace-kernel,
linux-doc, linux-perf-users
On Tue, 1 Sep 2026 09:47:17 +0900
"Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> 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().
>
> Fixes: c440adfbe302 ("tracing/probes: Support BTF based data structure field access")
> Cc: stable@vger.kernel.org
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://lore.kernel.org/all/20260822095110.0772E1F000E9@smtp.kernel.org/
> Assisted-by: Antigravity:gemini-3.7-flash
> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> ---
> @@ -661,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;
> + }
Is this just to fix the indentation? If so, can you make this a separate
patch? We don't need it to be part of a patch that gets backported. It may
make it more difficult to do so.
-- Steve
>
> if (next)
> ctx->offset += next - fieldname;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access
2026-09-01 13:04 ` Steven Rostedt
@ 2026-09-01 14:00 ` Masami Hiramatsu
0 siblings, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2026-09-01 14:00 UTC (permalink / raw)
To: Steven Rostedt
Cc: Peter Zijlstra, Ingo Molnar, x86, Jinchao Wang, Mathieu Desnoyers,
Thomas Gleixner, Borislav Petkov, Dave Hansen, H . Peter Anvin,
Alexander Shishkin, Ian Rogers, linux-kernel, linux-trace-kernel,
linux-doc, linux-perf-users
On Tue, 1 Sep 2026 09:04:42 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Tue, 1 Sep 2026 09:47:17 +0900
> "Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
>
> > From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> >
> > 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().
> >
> > Fixes: c440adfbe302 ("tracing/probes: Support BTF based data structure field access")
> > Cc: stable@vger.kernel.org
> > Reported-by: Sashiko <sashiko-bot@kernel.org>
> > Closes: https://lore.kernel.org/all/20260822095110.0772E1F000E9@smtp.kernel.org/
> > Assisted-by: Antigravity:gemini-3.7-flash
> > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> > ---
>
>
> > @@ -661,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;
> > + }
>
> Is this just to fix the indentation? If so, can you make this a separate
> patch? We don't need it to be part of a patch that gets backported. It may
> make it more difficult to do so.
OK, let me split it.
Thanks,
>
> -- Steve
>
>
> >
> > if (next)
> > ctx->offset += next - fieldname;
>
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-01 14:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 0:46 [PATCH v2 0/2] tracing/probes: Fix BTF structure member finder Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 1/2] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Masami Hiramatsu (Google)
2026-09-01 0:47 ` [PATCH v2 2/2] tracing/probes: Fix BTF kflag check for anonymous struct member access Masami Hiramatsu (Google)
2026-09-01 13:04 ` Steven Rostedt
2026-09-01 14:00 ` Masami Hiramatsu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox