From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
To: Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Tom Zanussi <zanussi@kernel.org>,
linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org,
donggeunyoo.kernel@gmail.com
Subject: [PATCH] tracing: Fix NULL dereference when copying keys for a field variable
Date: Sat, 12 Sep 2026 18:47:22 +0900 [thread overview]
Message-ID: <20260912094722.3271147-1-donggeunyoo.kernel@gmail.com> (raw)
create_field_var_hist() builds a hist trigger on the onmatch() event by
copying the key list of the compatible histogram found there, reading
each name from key_field->field->name. That pointer is NULL when the key
is not an event field: parse_field() leaves it NULL for common_cpu,
common_comm, common_timestamp, common_stacktrace and hitcount.
compatible_keys() compares only the type, size and signedness of each
key, so two common_cpu keys match and the loop faults.
The generated trigger is a real histogram whose element the variable is
later read out of, so it has to bucket the same way as the one it
mirrors. Render the keys with expr_field_str(), which carries .log2 and
.usecs, modifiers that change a key's value. Two things it did not carry
are added here. get_hist_field_flags() reports .stacktrace for the
common_stacktrace pseudo-field too, which parse_field() takes only on a
real field, so gate it on having one. And it reports a bare "buckets"
with the size held separately in hist_field->buckets, so append that the
way hist_field_print() does. expr_field_str() also renders expression
operands, so an expression over a bucketed field now prints the size
too, matching what hist_field_print() already shows for the key.
# echo 'hist:keys=common_cpu:ts0=common_timestamp.usecs' > \
events/sched/sched_waking/trigger
# echo 'my_synth u64 lat; int prio' > synthetic_events
# echo 'hist:keys=common_cpu:wakeup_lat=common_timestamp.usecs-$ts0:\
onmatch(sched.sched_waking).my_synth($wakeup_lat,prio)' > \
events/sched/sched_switch/trigger
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000002
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:action_create+0x1cb4/0x2e50
Call Trace:
event_hist_trigger_parse+0x3e47/0x69e0
trigger_process_regex+0x1a6/0x250
event_trigger_write+0xce/0x160
vfs_write+0x1cf/0xde0
ksys_write+0xfd/0x200
do_syscall_64+0xda/0x4b0
Cc: stable@vger.kernel.org
Fixes: 02205a6752f2 ("tracing: Add support for 'field variables'")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Assisted-by: Claude:claude-fable-5 [checkpatch]
---
QEMU, x86_64, CONFIG_KASAN=y, base 7.3.0-rc2-00020-g815e07c8fe88.
Eleven key kinds, one harness, both arms. Unpatched, common_cpu, common_comm,
common_timestamp, common_timestamp.usecs, common_stacktrace, hitcount and a
constant key each oops; pid, pid.log2, pid.buckets=10 and pid.buckets=64
survive and mirror as keys=pid. Patched, every one of the eleven generates a
histogram keyed exactly as the one it mirrors.
ftracetest test.d/trigger/: 37 passed, 5 failed, 0 unresolved, per-test
verdicts identical between the arms, "test field variable support" passing.
All five failures reproduce on the unpatched base.
kernel/trace/trace_events_hist.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 8af97fd4ee2d..257f5012a4fa 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1725,7 +1725,7 @@ static const char *get_hist_field_flags(struct hist_field *hist_field)
flags_str = "percent";
else if (hist_field->flags & HIST_FIELD_FL_GRAPH)
flags_str = "graph";
- else if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
+ else if (hist_field->flags & HIST_FIELD_FL_STACKTRACE && hist_field->field)
flags_str = "stacktrace";
return flags_str;
@@ -1754,6 +1754,9 @@ static bool expr_field_str(struct hist_field *field, struct seq_buf *s)
seq_buf_printf(s, ".%s", flags_str);
}
+ if (field->buckets)
+ seq_buf_printf(s, "=%ld", field->buckets);
+
return !seq_buf_has_overflowed(s);
}
@@ -3090,7 +3093,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,
key_field = hist_data->fields[i];
if (!first)
seq_buf_putc(&s, ',');
- seq_buf_puts(&s, key_field->field->name);
+ expr_field_str(key_field, &s);
first = false;
}
--
2.53.0
next reply other threads:[~2026-09-12 9:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-12 9:47 Donggeun Yoo [this message]
2026-09-13 16:25 ` Steven Rostedt
2026-09-13 17:32 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260912094722.3271147-1-donggeunyoo.kernel@gmail.com \
--to=donggeunyoo.kernel@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=rostedt@goodmis.org \
--cc=zanussi@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®