* [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events
@ 2026-11-09 0:28 Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 01/12] tracing/probes: Check enabled and busy state before unlinking sibling probes Masami Hiramatsu (Google)
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
Hi,
This series fixes several bugs in dynamic probe events (kprobe, fprobe,
uprobe, and eprobe) and BTF/fetch-argument handling:
- [01/12] Check whether the target event is enabled or busy before
unlinking a sibling probe during multiprobe unregistration, and add
the missing checks to trace_uprobe and trace_eprobe.
- [02/12] Enable newly appended fprobes and uprobes immediately when
the target multiprobe event is already enabled, matching trace_kprobe
behavior.
- [03/12] Fix BTF bitfield parsing for non-kflag bitfields (such as
enum bitfields), select a narrow container fetch type to avoid
out-of-bounds buffer writes, and compute bitfield extraction
parameters from the container width with bounds validation.
- [04/12] Add missing BTF_KIND_PTR, NULL, and BTF_KIND_INT checks in
btf_type_is_char_ptr() and btf_type_is_char_array().
- [05/12] Use explicit fixed-width integer types (s8/u8, s16/u16,
s32/u32) in eprobe get_event_field() so 1-byte signed fields are
properly sign-extended under -funsigned-char.
- [06/12] Disallow attaching eprobes to fprobe events to prevent
potential recursion issues, matching kprobes and uprobes.
- [07/12] Check FETCH_OP_UDEREF before advancing the fetch instruction
pointer in finalize_fetch_insn() so user-space dereference string
arrays emit FETCH_OP_ST_USTRING instead of FETCH_OP_ST_STRING.
Minor updates/cleanups:
- [08/12] Reject array specifiers on non-dereference string sources
(such as $comm or symstr) in finalize_fetch_insn().
- [09/12] Allow the symstr type on function entry arguments ($argN) in
return probes (FETCH_OP_EDATA).
- [10/12] Reject empty fetch expressions before :%pd and :%pD in
traceprobe_expand_dentry_args().
- [11/12] Validate the command prefix in kprobe, uprobe, and eprobe
creation when the colon separator is omitted so invalid prefixes are
rejected.
- [12/12] Propagate actual error return codes in eprobe and fprobe
creation paths instead of overwriting them with -EINVAL.
Notes:
- These bugs were identified and the fixes and cover letter were
prepared with the assistance of an LLM coding assistant.
Thank you,
---
base-commit: be94710b1f6ba1bea33e73129c110af80e999b2d
Masami Hiramatsu (Google) (12):
tracing/probes: Check enabled and busy state before unlinking sibling probes
tracing/probes: Enable newly appended probe when target event is enabled
tracing/probes: Fix BTF bitfield parsing and out-of-bounds buffer write
tracing/probes: Fix missing BTF kind checks in char pointer/array helpers
tracing/eprobe: Fix 1-byte signed field fetch in get_event_field()
tracing/eprobe: Disallow attaching eprobes to fprobe events
tracing/probes: Fix user-space dereference string array store type
tracing/probes: Reject array count on non-dereference string sources
tracing/probes: Allow symstr type for function entry arguments in return probes
tracing/probes: Reject empty fetch expression for %pd and %pD
tracing/probes: Validate command prefix in kprobe, uprobe, and eprobe
tracing/probes: Propagate error codes in eprobe and fprobe creation
kernel/trace/trace_eprobe.c | 39 ++++++++++++-------
kernel/trace/trace_fprobe.c | 26 ++++++-------
kernel/trace/trace_kprobe.c | 11 +++--
kernel/trace/trace_probe.c | 88 ++++++++++++++++++++++++++++++++++---------
kernel/trace/trace_uprobe.c | 76 +++++++++++++++++++++++++------------
5 files changed, 165 insertions(+), 75 deletions(-)
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 01/12] tracing/probes: Check enabled and busy state before unlinking sibling probes
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 02/12] tracing/probes: Enable newly appended probe when target event is enabled Masami Hiramatsu (Google)
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
When a multiprobe event is enabled or referenced (for example, by an
eprobe, trigger, or open tracefs file) and a user attempts to delete the
event or one of its probes via dynamic_events, checking
trace_probe_has_sibling() before the enabled and busy checks allows the
first probe to be unlinked and freed while the event is still active,
only returning -EBUSY on the last sibling probe. For uprobe events,
unlinking and freeing an enabled sibling probe without unregistering its
uprobe_consumer also causes a use-after-free.
Ensure all four probe types (kprobe, fprobe, uprobe, and eprobe) verify
that the event is neither enabled nor busy before unlinking any sibling
probe.
Fixes: ca89bc071d5e ("tracing/kprobe: Add multi-probe per event support")
Fixes: 41af3cf587f4 ("tracing/uprobe: Add multi-probe per uprobe event support")
Fixes: 7491e2c44278 ("tracing: Add a probe that attaches to trace events")
Fixes: 334e5519c375 ("tracing/probes: Add fprobe events for tracing function entry and exit.")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_eprobe.c | 12 ++++++++----
kernel/trace/trace_fprobe.c | 8 ++++----
kernel/trace/trace_kprobe.c | 8 ++++----
kernel/trace/trace_uprobe.c | 8 ++++++--
4 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index 474be2f5ccd9..f1590c9af6b2 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -94,14 +94,18 @@ static int eprobe_dyn_event_show(struct seq_file *m, struct dyn_event *ev)
static int unregister_trace_eprobe(struct trace_eprobe *ep)
{
- /* If other probes are on the event, just unregister eprobe */
- if (trace_probe_has_sibling(&ep->tp))
- goto unreg;
-
/* Enabled event can not be unregistered */
if (trace_probe_is_enabled(&ep->tp))
return -EBUSY;
+ /* If there's a reference to the dynamic event */
+ if (trace_event_dyn_busy(trace_probe_event_call(&ep->tp)))
+ return -EBUSY;
+
+ /* If other probes are on the event, just unregister eprobe */
+ if (trace_probe_has_sibling(&ep->tp))
+ goto unreg;
+
/* Will fail if probe is being used by ftrace or perf */
if (trace_probe_unregister_event_call(&ep->tp))
return -EBUSY;
diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
index 4e9034ebc3fb..77f2228d44ba 100644
--- a/kernel/trace/trace_fprobe.c
+++ b/kernel/trace/trace_fprobe.c
@@ -853,10 +853,6 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf)
/* Unregister a trace_probe and probe_event */
static int unregister_trace_fprobe(struct trace_fprobe *tf)
{
- /* If other probes are on the event, just unregister fprobe */
- if (trace_probe_has_sibling(&tf->tp))
- goto unreg;
-
/* Enabled event can not be unregistered */
if (trace_probe_is_enabled(&tf->tp))
return -EBUSY;
@@ -865,6 +861,10 @@ static int unregister_trace_fprobe(struct trace_fprobe *tf)
if (trace_event_dyn_busy(trace_probe_event_call(&tf->tp)))
return -EBUSY;
+ /* If other probes are on the event, just unregister fprobe */
+ if (trace_probe_has_sibling(&tf->tp))
+ goto unreg;
+
/* Will fail if probe is being used by ftrace or perf */
if (unregister_fprobe_event(tf))
return -EBUSY;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index e41a7c113646..a42af0e66009 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -548,10 +548,6 @@ static void __unregister_trace_kprobe(struct trace_kprobe *tk)
/* Unregister a trace_probe and probe_event */
static int unregister_trace_kprobe(struct trace_kprobe *tk)
{
- /* If other probes are on the event, just unregister kprobe */
- if (trace_probe_has_sibling(&tk->tp))
- goto unreg;
-
/* Enabled event can not be unregistered */
if (trace_probe_is_enabled(&tk->tp))
return -EBUSY;
@@ -560,6 +556,10 @@ static int unregister_trace_kprobe(struct trace_kprobe *tk)
if (trace_event_dyn_busy(trace_probe_event_call(&tk->tp)))
return -EBUSY;
+ /* If other probes are on the event, just unregister kprobe */
+ if (trace_probe_has_sibling(&tk->tp))
+ goto unreg;
+
/* Will fail if probe is being used by ftrace or perf */
if (unregister_kprobe_event(tk))
return -EBUSY;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 22cc3c8181b8..146da04b93a8 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -396,13 +396,17 @@ static int unregister_trace_uprobe(struct trace_uprobe *tu)
{
int ret;
- if (trace_probe_has_sibling(&tu->tp))
- goto unreg;
+ /* Enabled event can not be unregistered */
+ if (trace_probe_is_enabled(&tu->tp))
+ return -EBUSY;
/* If there's a reference to the dynamic event */
if (trace_event_dyn_busy(trace_probe_event_call(&tu->tp)))
return -EBUSY;
+ if (trace_probe_has_sibling(&tu->tp))
+ goto unreg;
+
ret = unregister_uprobe_event(tu);
if (ret)
return ret;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 02/12] tracing/probes: Enable newly appended probe when target event is enabled
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 01/12] tracing/probes: Check enabled and busy state before unlinking sibling probes Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 03/12] tracing/probes: Fix BTF bitfield parsing and out-of-bounds buffer write Masami Hiramatsu (Google)
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Unlike kprobe events, fprobe and uprobe events only register their
underlying probes when the trace event is enabled. When a new probe is
appended to an existing multiprobe fprobe or uprobe event that is
already enabled, the appended probe is linked into the event's probe
list without being registered.
As a result, the newly appended probe never fires until the event is
disabled and re-enabled. Moreover, disabling an fprobe event calls
unregister_fprobe() on the unregistered fprobe, and opening or closing a
perf event on an enabled uprobe event dereferences a NULL tu->uprobe in
uprobe_apply().
Register and enable the newly appended fprobe or uprobe immediately when
the target event is already enabled.
Fixes: 41af3cf587f4 ("tracing/uprobe: Add multi-probe per uprobe event support")
Fixes: 2db832ec9090 ("tracing: fprobe-events: Register fprobe-events only when it is enabled")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_fprobe.c | 14 +++++------
kernel/trace/trace_uprobe.c | 56 ++++++++++++++++++++++++++++---------------
2 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
index 77f2228d44ba..9ab0871a6461 100644
--- a/kernel/trace/trace_fprobe.c
+++ b/kernel/trace/trace_fprobe.c
@@ -933,7 +933,10 @@ static int append_trace_fprobe_event(struct trace_fprobe *tf, struct trace_fprob
if (ret)
return ret;
- ret = trace_fprobe_verify_target(tf);
+ if (trace_probe_is_enabled(&tf->tp))
+ ret = __register_trace_fprobe(tf);
+ else
+ ret = trace_fprobe_verify_target(tf);
if (ret)
trace_probe_unlink(&tf->tp);
else
@@ -1520,13 +1523,8 @@ static int disable_trace_fprobe(struct trace_event_call *call,
trace_probe_clear_flag(tp, TP_FLAG_PROFILE);
if (!trace_probe_is_enabled(tp)) {
- list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) {
- unregister_fprobe(&tf->fp);
- if (tf->tuser) {
- tracepoint_user_put(tf->tuser);
- tf->tuser = NULL;
- }
- }
+ list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list)
+ __unregister_trace_fprobe(tf);
}
out:
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 146da04b93a8..14ac52aebe34 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -447,6 +447,28 @@ static bool trace_uprobe_has_same_uprobe(struct trace_uprobe *orig,
return false;
}
+typedef bool (*filter_func_t)(struct uprobe_consumer *self, struct mm_struct *mm);
+
+#ifdef CONFIG_PERF_EVENTS
+static bool uprobe_perf_filter(struct uprobe_consumer *uc, struct mm_struct *mm);
+#else
+#define uprobe_perf_filter NULL
+#endif
+
+static int trace_uprobe_enable(struct trace_uprobe *tu, filter_func_t filter)
+{
+ struct inode *inode = d_real_inode(tu->path.dentry);
+ struct uprobe *uprobe;
+
+ tu->consumer.filter = filter;
+ uprobe = uprobe_register(inode, tu->offset, tu->ref_ctr_offset, &tu->consumer);
+ if (IS_ERR(uprobe))
+ return PTR_ERR(uprobe);
+
+ tu->uprobe = uprobe;
+ return 0;
+}
+
static int append_trace_uprobe(struct trace_uprobe *tu, struct trace_uprobe *to)
{
int ret;
@@ -466,10 +488,22 @@ static int append_trace_uprobe(struct trace_uprobe *tu, struct trace_uprobe *to)
/* Append to existing event */
ret = trace_probe_append(&tu->tp, &to->tp);
- if (!ret)
- dyn_event_add(&tu->devent, trace_probe_event_call(&tu->tp));
+ if (ret)
+ return ret;
- return ret;
+ if (trace_probe_is_enabled(&tu->tp)) {
+ ret = trace_uprobe_enable(tu,
+ trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE) ?
+ uprobe_perf_filter : NULL);
+ if (ret) {
+ trace_probe_unlink(&tu->tp);
+ return ret;
+ }
+ }
+
+ dyn_event_add(&tu->devent, trace_probe_event_call(&tu->tp));
+
+ return 0;
}
/*
@@ -1105,22 +1139,6 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e
return trace_handle_return(s);
}
-typedef bool (*filter_func_t)(struct uprobe_consumer *self, struct mm_struct *mm);
-
-static int trace_uprobe_enable(struct trace_uprobe *tu, filter_func_t filter)
-{
- struct inode *inode = d_real_inode(tu->path.dentry);
- struct uprobe *uprobe;
-
- tu->consumer.filter = filter;
- uprobe = uprobe_register(inode, tu->offset, tu->ref_ctr_offset, &tu->consumer);
- if (IS_ERR(uprobe))
- return PTR_ERR(uprobe);
-
- tu->uprobe = uprobe;
- return 0;
-}
-
static void __probe_event_disable(struct trace_probe *tp)
{
struct trace_uprobe *tu;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 03/12] tracing/probes: Fix BTF bitfield parsing and out-of-bounds buffer write
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 01/12] tracing/probes: Check enabled and busy state before unlinking sibling probes Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 02/12] tracing/probes: Enable newly appended probe when target event is enabled Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 04/12] tracing/probes: Fix missing BTF kind checks in char pointer/array helpers Masami Hiramatsu (Google)
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
BTF bitfield parsing in trace_probe.c assumes a 64-bit (8-byte) container
when computing FETCH_OP_MOD_BF shift amounts and basesize, whereas the
preceding store instruction only allocates and writes the field's fetch
type size (which may be 1, 2, or 4 bytes when kflag=1). At runtime,
fetch_apply_bitfield() performs an 8-byte read-modify-write on the
smaller ring buffer slot, corrupting adjacent ring buffer data or writing
past the end of the event record.
In addition, signed bitfields with bit widths other than 8/16/32/64 fail
to resolve a fetch type, bitfields whose width is a multiple of 8 inside
a larger integer or spanning a byte boundary fail to emit FETCH_OP_MOD_BF
or select a container wide enough for bitoffs + bitsize, and kflag=0
bitfield offsets >= 8 bits are not folded into the byte offset.
Compute the bitfield byte and bit offsets consistently during field
lookup, select the smallest unsigned fetch type that covers the bit
offset and bit width, and calculate the FETCH_OP_MOD_BF parameters from
the selected fetch type size.
Fixes: c440adfbe302 ("tracing/probes: Support BTF based data structure field access")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 55 +++++++++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index a880a90642d7..26e02929f1ff 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -486,6 +486,18 @@ static const char *fetch_type_from_btf_type(struct btf *btf,
{
u32 intdata;
+ if (ctx->last_bitsize) {
+ u32 bits = ctx->last_bitsize + ctx->last_bitoffs;
+
+ if (bits <= 8)
+ return "u8";
+ if (bits <= 16)
+ return "u16";
+ if (bits <= 32)
+ return "u32";
+ return "u64";
+ }
+
/* TODO: const char * could be converted as a string */
switch (BTF_INFO_KIND(type->info)) {
case BTF_KIND_ENUM:
@@ -520,10 +532,6 @@ static const char *fetch_type_from_btf_type(struct btf *btf,
case 64:
return "u64";
}
- /* bitfield, size is encoded in the type */
- ctx->last_bitsize = BTF_INT_BITS(intdata);
- ctx->last_bitoffs += BTF_INT_OFFSET(intdata);
- return "u64";
}
}
/* TODO: support other types */
@@ -653,6 +661,12 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty
/* Add anonymous structure/union offset */
bitoffs += anon_offs;
+ type = btf_type_skip_modifiers(btf, field->type, NULL);
+ if (!type) {
+ trace_probe_log_err(ctx->offset, BAD_BTF_TID);
+ return -EINVAL;
+ }
+
/* Accumulate the bit-offsets of the dot-connected fields */
if (btf_type_kflag(container_type)) {
bitoffs += BTF_MEMBER_BIT_OFFSET(field->offset);
@@ -660,12 +674,15 @@ static int get_bitoffset_of_field(char **pfieldname, const struct btf_type **pty
} else {
bitoffs += field->offset;
ctx->last_bitsize = 0;
- }
+ if (BTF_INFO_KIND(type->info) == BTF_KIND_INT) {
+ u32 intdata = btf_type_int(type);
- type = btf_type_skip_modifiers(btf, field->type, NULL);
- if (!type) {
- trace_probe_log_err(ctx->offset, BAD_BTF_TID);
- return -EINVAL;
+ if (BTF_INT_OFFSET(intdata) ||
+ BTF_INT_BITS(intdata) != BYTES_TO_BITS(type->size)) {
+ bitoffs += BTF_INT_OFFSET(intdata);
+ ctx->last_bitsize = BTF_INT_BITS(intdata);
+ }
+ }
}
if (next)
@@ -858,13 +875,22 @@ static const struct fetch_type *find_fetch_type_from_btf_type(
}
static int parse_btf_bitfield(struct fetch_insn **pcode,
+ const struct fetch_type *t,
struct traceprobe_parse_context *ctx)
{
struct fetch_insn *code = *pcode;
- if ((ctx->last_bitsize % 8 == 0) && ctx->last_bitoffs == 0)
+ if ((ctx->last_bitsize == 0 ||
+ ctx->last_bitsize == BYTES_TO_BITS(t->size)) &&
+ ctx->last_bitoffs == 0)
return 0;
+ if (ctx->last_bitsize == 0 ||
+ BYTES_TO_BITS(t->size) < (ctx->last_bitsize + ctx->last_bitoffs)) {
+ trace_probe_log_err(ctx->offset, BAD_BITFIELD);
+ return -EINVAL;
+ }
+
code++;
if (code->op != FETCH_OP_NOP) {
trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
@@ -873,9 +899,9 @@ static int parse_btf_bitfield(struct fetch_insn **pcode,
*pcode = code;
code->op = FETCH_OP_MOD_BF;
- code->lshift = 64 - (ctx->last_bitsize + ctx->last_bitoffs);
- code->rshift = 64 - ctx->last_bitsize;
- code->basesize = 64 / 8;
+ code->lshift = BYTES_TO_BITS(t->size) - (ctx->last_bitsize + ctx->last_bitoffs);
+ code->rshift = BYTES_TO_BITS(t->size) - ctx->last_bitsize;
+ code->basesize = t->size;
return 0;
}
@@ -1085,6 +1111,7 @@ static int parse_btf_arg(char *varname,
}
static int parse_btf_bitfield(struct fetch_insn **pcode,
+ const struct fetch_type *t,
struct traceprobe_parse_context *ctx)
{
trace_probe_log_err(ctx->offset, NOSUP_BTFARG);
@@ -1995,7 +2022,7 @@ static int finalize_fetch_insn(struct fetch_insn *code,
} else if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) &&
ctx->last_type) {
/* If user not specified the type, try parsing BTF bitfield. */
- ret = parse_btf_bitfield(&code, ctx);
+ ret = parse_btf_bitfield(&code, parg->type, ctx);
if (ret)
return ret;
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 04/12] tracing/probes: Fix missing BTF kind checks in char pointer/array helpers
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (2 preceding siblings ...)
2026-11-09 0:28 ` [PATCH 03/12] tracing/probes: Fix BTF bitfield parsing and out-of-bounds buffer write Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 05/12] tracing/eprobe: Fix 1-byte signed field fetch in get_event_field() Masami Hiramatsu (Google)
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
In struct btf_type, the type ID and byte size share a union, and only
BTF_KIND_INT types are followed by a 32-bit integer encoding word.
Because btf_type_is_char_ptr() and btf_type_is_char_array() do not
verify that the outer type is BTF_KIND_PTR or that the resolved element
type is a non-NULL BTF_KIND_INT before inspecting it, non-pointer BTF
types can have their byte size misinterpreted as a BTF type ID, and
arrays of non-integer types read out-of-bounds or misinterpret trailing
BTF metadata as BTF_INT_* encoding bits.
Validate the BTF type kinds and NULL pointers before reading inner type
metadata in both helpers.
Fixes: 27973e5c64b9 ("tracing/probes: Add string type check with BTF")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 26e02929f1ff..829fa6559b59 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -411,6 +411,9 @@ static bool btf_type_is_char_ptr(struct btf *btf, const struct btf_type *type)
const struct btf_type *real_type;
u32 intdata;
+ if (BTF_INFO_KIND(type->info) != BTF_KIND_PTR)
+ return false;
+
real_type = btf_type_skip_modifiers(btf, type->type, NULL);
if (!real_type)
return false;
@@ -435,6 +438,11 @@ static bool btf_type_is_char_array(struct btf *btf, const struct btf_type *type)
array = (const struct btf_array *)(type + 1);
real_type = btf_type_skip_modifiers(btf, array->type, NULL);
+ if (!real_type)
+ return false;
+
+ if (BTF_INFO_KIND(real_type->info) != BTF_KIND_INT)
+ return false;
intdata = btf_type_int(real_type);
return !(BTF_INT_ENCODING(intdata) & BTF_INT_SIGNED)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 05/12] tracing/eprobe: Fix 1-byte signed field fetch in get_event_field()
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (3 preceding siblings ...)
2026-11-09 0:28 ` [PATCH 04/12] tracing/probes: Fix missing BTF kind checks in char pointer/array helpers Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 06/12] tracing/eprobe: Disallow attaching eprobes to fprobe events Masami Hiramatsu (Google)
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Because the kernel is built with -funsigned-char, plain 'char' is
unsigned on all architectures. Reading 1-byte signed trace event fields
via *(char *)addr in get_event_field() therefore zero-extends instead of
sign-extending negative s8 values.
Use explicit fixed-width integer types (s8/u8, s16/u16, s32/u32) when
reading event fields.
Fixes: 7491e2c44278 ("tracing: Add a probe that attaches to trace events")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_eprobe.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index f1590c9af6b2..9defe86f4e8f 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -334,21 +334,21 @@ get_event_field(struct fetch_insn *code, void *rec)
switch (field->size) {
case 1:
if (field->is_signed)
- val = *(char *)addr;
+ val = *(s8 *)addr;
else
- val = *(unsigned char *)addr;
+ val = *(u8 *)addr;
break;
case 2:
if (field->is_signed)
- val = *(short *)addr;
+ val = *(s16 *)addr;
else
- val = *(unsigned short *)addr;
+ val = *(u16 *)addr;
break;
case 4:
if (field->is_signed)
- val = *(int *)addr;
+ val = *(s32 *)addr;
else
- val = *(unsigned int *)addr;
+ val = *(u32 *)addr;
break;
default:
if (field->size == sizeof(long)) {
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 06/12] tracing/eprobe: Disallow attaching eprobes to fprobe events
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (4 preceding siblings ...)
2026-11-09 0:28 ` [PATCH 05/12] tracing/eprobe: Fix 1-byte signed field fetch in get_event_field() Masami Hiramatsu (Google)
@ 2026-11-09 0:28 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 07/12] tracing/probes: Fix user-space dereference string array store type Masami Hiramatsu (Google)
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Event probes (eprobes) are not allowed to attach to other dynamic probe
events (kprobes, uprobes, and eprobes) to avoid recursive probe chains
and lifecycle dependencies. However, when fprobe events were introduced,
TRACE_EVENT_FL_FPROBE was omitted from the exclusion mask in
find_and_get_event(), allowing eprobes to attach to fprobe and tprobe
events.
Exclude TRACE_EVENT_FL_FPROBE events in find_and_get_event().
Fixes: 334e5519c375 ("tracing/probes: Add fprobe events for tracing function entry and exit.")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_eprobe.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index 9defe86f4e8f..f65393fb1c10 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -762,7 +762,8 @@ find_and_get_event(const char *system, const char *event_name)
(TRACE_EVENT_FL_IGNORE_ENABLE |
TRACE_EVENT_FL_KPROBE |
TRACE_EVENT_FL_UPROBE |
- TRACE_EVENT_FL_EPROBE))
+ TRACE_EVENT_FL_EPROBE |
+ TRACE_EVENT_FL_FPROBE))
continue;
if (!tp_event->class->system ||
strcmp(system, tp_event->class->system))
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 07/12] tracing/probes: Fix user-space dereference string array store type
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (5 preceding siblings ...)
2026-11-09 0:28 ` [PATCH 06/12] tracing/eprobe: Disallow attaching eprobes to fprobe events Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 08/12] tracing/probes: Reject array count on non-dereference string sources Masami Hiramatsu (Google)
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
When finalizing a string array argument (e.g. +0u(%reg):string[N]),
finalize_fetch_insn() advances the instruction pointer to a new slot
for the store operation before checking whether the preceding operation
was FETCH_OP_UDEREF. As a result, user-space dereference string arrays
with type "string" emit FETCH_OP_ST_STRING (kernel memory read) instead
of FETCH_OP_ST_USTRING.
Check for FETCH_OP_UDEREF before advancing the instruction pointer.
Fixes: e65f7ae7f4da ("tracing/probe: Support user-space dereference")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 829fa6559b59..e62acf05a8ee 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1952,6 +1952,8 @@ static int finalize_fetch_insn(struct fetch_insn *code,
/* Store operation */
if (parg->type->is_string) {
+ bool is_uderef;
+
/* Check bad combination of the type and the last fetch_insn. */
if (!strcmp(parg->type->name, "symstr")) {
if (code->op != FETCH_OP_REG && code->op != FETCH_OP_STACK &&
@@ -1971,6 +1973,7 @@ static int finalize_fetch_insn(struct fetch_insn *code,
}
}
+ is_uderef = (code->op == FETCH_OP_UDEREF);
if (!strcmp(parg->type->name, "symstr") ||
(code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM ||
code->op == FETCH_OP_IMMSTR) || code->op == FETCH_OP_TP_ARG ||
@@ -1991,8 +1994,7 @@ static int finalize_fetch_insn(struct fetch_insn *code,
}
/* If op == DEREF, replace it with STRING */
- if (!strcmp(parg->type->name, "ustring") ||
- code->op == FETCH_OP_UDEREF)
+ if (!strcmp(parg->type->name, "ustring") || is_uderef)
code->op = FETCH_OP_ST_USTRING;
else if (!strcmp(parg->type->name, "symstr"))
code->op = FETCH_OP_ST_SYMSTR;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 08/12] tracing/probes: Reject array count on non-dereference string sources
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (6 preceding siblings ...)
2026-11-09 0:29 ` [PATCH 07/12] tracing/probes: Fix user-space dereference string array store type Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 09/12] tracing/probes: Allow symstr type for function entry arguments in return probes Masami Hiramatsu (Google)
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
The runtime array loop (FETCH_OP_LP_ARRAY) for string types requires a
preceding memory dereference instruction so it can advance the pointer
address on each iteration. Non-dereference string sources such as $comm,
immediate strings, and eprobe event fields cannot be indexed as pointer
arrays, but finalize_fetch_insn() still accepts an array count on them
and emits an invalid FETCH_OP_LP_ARRAY sequence.
Reject string array counts when the preceding operation is not a memory
dereference.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index e62acf05a8ee..0f544d415153 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1986,6 +1986,12 @@ static int finalize_fetch_insn(struct fetch_insn *code,
* For the symstr, it doesn't need to dereference, thus
* it just get the value.
*/
+ if (parg->count && (code->op != FETCH_OP_DEREF &&
+ code->op != FETCH_OP_UDEREF)) {
+ trace_probe_log_err(ctx->offset + type_offset,
+ BAD_STRING);
+ return -EINVAL;
+ }
code++;
if (code->op != FETCH_OP_NOP) {
trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 09/12] tracing/probes: Allow symstr type for function entry arguments in return probes
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (7 preceding siblings ...)
2026-11-09 0:29 ` [PATCH 08/12] tracing/probes: Reject array count on non-dereference string sources Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 10/12] tracing/probes: Reject empty fetch expression for %pd and %pD Masami Hiramatsu (Google)
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Function entry arguments accessed in return probes ($argN or BTF entry
arguments) are fetched from the entry data buffer via FETCH_OP_EDATA,
which was omitted from the allowed operations for the "symstr" type and
rejected with BAD_SYMSTRING.
Allow FETCH_OP_EDATA to be formatted as "symstr".
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 0f544d415153..67453d0121c9 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1958,7 +1958,8 @@ static int finalize_fetch_insn(struct fetch_insn *code,
if (!strcmp(parg->type->name, "symstr")) {
if (code->op != FETCH_OP_REG && code->op != FETCH_OP_STACK &&
code->op != FETCH_OP_RETVAL && code->op != FETCH_OP_ARG &&
- code->op != FETCH_OP_DEREF && code->op != FETCH_OP_TP_ARG) {
+ code->op != FETCH_OP_DEREF && code->op != FETCH_OP_TP_ARG &&
+ code->op != FETCH_OP_EDATA) {
trace_probe_log_err(ctx->offset + type_offset,
BAD_SYMSTRING);
return -EINVAL;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 10/12] tracing/probes: Reject empty fetch expression for %pd and %pD
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (8 preceding siblings ...)
2026-11-09 0:29 ` [PATCH 09/12] tracing/probes: Allow symstr type for function entry arguments in return probes Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 11/12] tracing/probes: Validate command prefix in kprobe, uprobe, and eprobe Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 12/12] tracing/probes: Propagate error codes in eprobe and fprobe creation Masami Hiramatsu (Google)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
When an argument ends with :%pd or :%pD but has an empty target fetch
expression (such as ":%pd" or "name=:%pd"), traceprobe_expand_dentry_args()
still expands it into an invalid nested dereference expression. The
subsequent parser failure then logs an error position pointing into the
expanded internal string past the end of the user's command.
Reject empty %pd and %pD fetch expressions upfront before expansion.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_probe.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 67453d0121c9..6e4fe9f6c722 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -2434,11 +2434,17 @@ int traceprobe_expand_dentry_args(int argc, const char *argv[], char **buf)
if (!tmp)
return -ENOMEM;
+ arg_len = strlen(argv[i]);
+ tmp[arg_len - 4] = '\0';
equal = strchr(tmp, '=');
if (equal)
*equal = '\0';
- arg_len = strlen(argv[i]);
- tmp[arg_len - 4] = '\0';
+ if (*(equal ? equal + 1 : tmp) == '\0') {
+ trace_probe_log_set_index(i + 2);
+ trace_probe_log_err(equal ? equal + 1 - tmp : 0,
+ BAD_FETCH_ARG);
+ return -EINVAL;
+ }
if (argv[i][arg_len - 1] == 'd')
ret = snprintf(tmpbuf + used, bufsize - used,
"%s%s+0x0(+0x%zx(%s)):string",
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 11/12] tracing/probes: Validate command prefix in kprobe, uprobe, and eprobe
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (9 preceding siblings ...)
2026-11-09 0:29 ` [PATCH 10/12] tracing/probes: Reject empty fetch expression for %pd and %pD Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 12/12] tracing/probes: Propagate error codes in eprobe and fprobe creation Masami Hiramatsu (Google)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
In kprobe, uprobe, and eprobe creation, trailing characters after the
command prefix ('p', 'r', or 'e') without a ':' separator (or non-digit
characters before ':') are silently ignored, creating a probe with the
default event name instead of reporting a syntax error as fprobe does.
Reject invalid characters following the command prefix with BAD_MAXACT.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_eprobe.c | 10 ++++++++--
kernel/trace/trace_kprobe.c | 3 +++
kernel/trace/trace_uprobe.c | 12 +++++++++---
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index f65393fb1c10..f65da7b3adf4 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -846,12 +846,18 @@ static int __trace_eprobe_create(int argc, const char *argv[])
trlog = trace_probe_log_init("event_probe", argc, argv);
- event = strchr(&argv[0][1], ':');
+ if (argv[0][1] != '\0') {
+ if (argv[0][1] != ':') {
+ trace_probe_log_set_index(0);
+ trace_probe_log_err(1, BAD_MAXACT);
+ return -EINVAL;
+ }
+ event = &argv[0][2];
+ }
if (event) {
gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
if (!gbuf)
return -ENOMEM;
- event++;
ret = traceprobe_parse_event_name(&event, &group, gbuf,
event - argv[0]);
if (ret)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index a42af0e66009..35568d75723c 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -941,6 +941,9 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
trace_probe_log_err(1, MAXACT_TOO_BIG);
return -EINVAL;
}
+ } else if (argv[0][1] != '\0' && argv[0][1] != ':') {
+ trace_probe_log_err(1, BAD_MAXACT);
+ return -EINVAL;
}
/* try to parse an address. if that fails, try to read the
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 14ac52aebe34..3745eb07bd14 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -616,9 +616,6 @@ static int __trace_uprobe_create(int argc, const char **argv)
return -E2BIG;
}
- if (argv[0][1] == ':')
- event = &argv[0][2];
-
if (!strchr(argv[1], '/'))
return -ECANCELED;
@@ -631,6 +628,15 @@ static int __trace_uprobe_create(int argc, const char **argv)
if (!arg || !isdigit(arg[1]))
return -ECANCELED;
+ if (argv[0][1] != '\0') {
+ if (argv[0][1] != ':') {
+ trace_probe_log_set_index(0);
+ trace_probe_log_err(1, BAD_MAXACT);
+ return -EINVAL;
+ }
+ event = &argv[0][2];
+ }
+
trace_probe_log_set_index(1); /* filename is the 2nd argument */
*arg++ = '\0';
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 12/12] tracing/probes: Propagate error codes in eprobe and fprobe creation
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
` (10 preceding siblings ...)
2026-11-09 0:29 ` [PATCH 11/12] tracing/probes: Validate command prefix in kprobe, uprobe, and eprobe Masami Hiramatsu (Google)
@ 2026-11-09 0:29 ` Masami Hiramatsu (Google)
11 siblings, 0 replies; 13+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-11-09 0:29 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
In __trace_eprobe_create() and trace_fprobe_create_internal(), error
codes returned by helper and registration functions (such as -ENOMEM or
-EEXIST) are overwritten with -EINVAL.
Propagate the actual error codes to the caller.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace_eprobe.c | 2 +-
kernel/trace/trace_fprobe.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
index f65da7b3adf4..d1477ff5b128 100644
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -917,7 +917,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
trace_probe_log_set_index(filter_idx);
ret = trace_eprobe_parse_filter(ep, filter_cnt, argv + filter_idx);
if (ret)
- return -EINVAL;
+ return ret;
} else
ep->filter_str = NULL;
diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
index 9ab0871a6461..f6bfc4073887 100644
--- a/kernel/trace/trace_fprobe.c
+++ b/kernel/trace/trace_fprobe.c
@@ -1272,7 +1272,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],
/* a symbol(or tracepoint) must be specified */
ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint);
if (ret < 0)
- return -EINVAL;
+ return ret;
trace_probe_log_set_index(0);
if (event) {
@@ -1388,7 +1388,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],
trace_probe_log_err(0, BAD_PROBE_ADDR);
else if (ret != -ENOMEM && ret != -EEXIST)
trace_probe_log_err(0, FAIL_REG_PROBE);
- return -EINVAL;
+ return ret;
}
/* 'tf' is successfully registered. To avoid freeing, assign NULL. */
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-11-09 0:29 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 0:28 [PATCH 00/12] tracing/probes: Fix various bugs in dynamic probe events Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 01/12] tracing/probes: Check enabled and busy state before unlinking sibling probes Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 02/12] tracing/probes: Enable newly appended probe when target event is enabled Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 03/12] tracing/probes: Fix BTF bitfield parsing and out-of-bounds buffer write Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 04/12] tracing/probes: Fix missing BTF kind checks in char pointer/array helpers Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 05/12] tracing/eprobe: Fix 1-byte signed field fetch in get_event_field() Masami Hiramatsu (Google)
2026-11-09 0:28 ` [PATCH 06/12] tracing/eprobe: Disallow attaching eprobes to fprobe events Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 07/12] tracing/probes: Fix user-space dereference string array store type Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 08/12] tracing/probes: Reject array count on non-dereference string sources Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 09/12] tracing/probes: Allow symstr type for function entry arguments in return probes Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 10/12] tracing/probes: Reject empty fetch expression for %pd and %pD Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 11/12] tracing/probes: Validate command prefix in kprobe, uprobe, and eprobe Masami Hiramatsu (Google)
2026-11-09 0:29 ` [PATCH 12/12] tracing/probes: Propagate error codes in eprobe and fprobe creation Masami Hiramatsu (Google)
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®