* [PATCH] tracing/filters: Check perf permissions before resolving .function
@ 2026-10-06 22:51 Kyle Zeng
2026-10-07 3:44 ` Masami Hiramatsu
0 siblings, 1 reply; 5+ messages in thread
From: Kyle Zeng @ 2026-10-06 22:51 UTC (permalink / raw)
To: linux-trace-kernel
Cc: linux-kernel, rostedt, mhiramat, outbounddisclosures, Kyle Zeng, stable
perf_trace_event_perm() allows tracepoint counters that do not request
PERF_SAMPLE_RAW without raw tracepoint permissions. A self-targeted,
disabled event with exclude_kernel=1 can therefore reach the filter
compiler even at perf_event_paranoid=2.
The .function suffix accepts any field of sizeof(long) and resolves its
operand through kallsyms_lookup_name() and kallsyms_lookup_size_offset().
The success or failure of a numeric filter discloses whether an address
belongs to a known kernel symbol range. On x86-64 this can be used to
recover the randomized kernel image base. A named filter also exposes
the resolved symbol range through the counter when the tracepoint field
is controlled by the caller, as with a syscall argument.
Pass the filter's perf origin to the predicate parser and require
perf_allow_tracepoint() before resolving a .function operand. This uses
the same sysctl, initial-namespace capability and LSM policy as raw
tracepoint access, and closes both the numeric and named-symbol oracles.
Do not change ordinary perf counting filters or filters created through
the separately controlled tracefs interfaces.
Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Kyle Zeng <kylebot@openai.com>
---
kernel/trace/trace_events_filter.c | 39 ++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 2b46ca536045..0f8c2054f4a7 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1625,12 +1625,18 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event)
}
}
+struct filter_parse_data {
+ struct trace_event_call *call;
+ bool is_perf;
+};
+
/* Called when a predicate is encountered by predicate_parse() */
static int parse_pred(const char *str, void *data,
int pos, struct filter_parse_error *pe,
struct filter_pred **pred_ptr)
{
- struct trace_event_call *call = data;
+ struct filter_parse_data *pdata = data;
+ struct trace_event_call *call = pdata->call;
struct ftrace_event_field *field;
struct filter_pred *pred = NULL;
unsigned long offset;
@@ -1683,6 +1689,14 @@ static int parse_pred(const char *str, void *data,
/* See if the field is a kernel function name */
if ((len = str_has_prefix(str + i, ".function"))) {
+ /* Even counting filters can disclose kernel addresses. */
+ if (pdata->is_perf) {
+ ret = perf_allow_tracepoint();
+ if (ret) {
+ parse_error(pe, ret, pos + i);
+ return ret;
+ }
+ }
function = true;
i += len;
}
@@ -2205,8 +2219,12 @@ static int calc_stack(const char *str, int *parens, int *preds, int *err)
static int process_preds(struct trace_event_call *call,
const char *filter_string,
struct event_filter *filter,
- struct filter_parse_error *pe)
+ struct filter_parse_error *pe, bool is_perf)
{
+ struct filter_parse_data data = {
+ .call = call,
+ .is_perf = is_perf,
+ };
struct prog_entry *prog;
int nr_parens;
int nr_preds;
@@ -2232,7 +2250,7 @@ static int process_preds(struct trace_event_call *call,
return -EINVAL;
prog = predicate_parse(filter_string, nr_parens, nr_preds,
- parse_pred, call, pe);
+ parse_pred, &data, pe);
if (IS_ERR(prog))
return PTR_ERR(prog);
@@ -2281,7 +2299,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir,
if (!filter->filter_string)
goto fail_mem;
- err = process_preds(file->event_call, filter_string, filter, pe);
+ err = process_preds(file->event_call, filter_string, filter, pe, false);
if (err) {
filter_disable(file);
parse_error(pe, FILT_ERR_BAD_SUBSYS_FILTER, 0);
@@ -2377,6 +2395,7 @@ static void create_filter_finish(struct filter_parse_error *pe)
* @call: trace_event_call to create a filter for
* @filter_string: filter string
* @set_str: remember @filter_str and enable detailed error in filter
+ * @is_perf: filter is being created for a perf event
* @filterp: out param for created filter (always updated on return)
* Must be a pointer that references a NULL pointer.
*
@@ -2391,7 +2410,7 @@ static void create_filter_finish(struct filter_parse_error *pe)
*/
static int create_filter(struct trace_array *tr,
struct trace_event_call *call,
- char *filter_string, bool set_str,
+ char *filter_string, bool set_str, bool is_perf,
struct event_filter **filterp)
{
struct filter_parse_error *pe = NULL;
@@ -2405,7 +2424,7 @@ static int create_filter(struct trace_array *tr,
if (err)
return err;
- err = process_preds(call, filter_string, *filterp, pe);
+ err = process_preds(call, filter_string, *filterp, pe, is_perf);
if (err && set_str)
append_filter_err(tr, pe, *filterp);
create_filter_finish(pe);
@@ -2418,7 +2437,7 @@ int create_event_filter(struct trace_array *tr,
char *filter_str, bool set_str,
struct event_filter **filterp)
{
- return create_filter(tr, call, filter_str, set_str, filterp);
+ return create_filter(tr, call, filter_str, set_str, false, filterp);
}
/**
@@ -2476,7 +2495,7 @@ int apply_event_filter(struct trace_event_file *file, char *filter_string)
return 0;
}
- err = create_filter(file->tr, call, filter_string, true, &filter);
+ err = create_filter(file->tr, call, filter_string, true, false, &filter);
/*
* Always swap the call filter with the new filter
@@ -2721,7 +2740,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
if (event->filter)
return -EEXIST;
- err = create_filter(NULL, call, filter_str, false, &filter);
+ err = create_filter(NULL, call, filter_str, false, true, &filter);
if (err)
goto free_filter;
@@ -2868,7 +2887,7 @@ static __init int ftrace_test_event_filter(void)
int err;
err = create_filter(NULL, &event_ftrace_test_filter,
- d->filter, false, &filter);
+ d->filter, false, false, &filter);
if (err) {
printk(KERN_INFO
"Failed to get filter for '%s', err %d\n",
base-commit: fd179f8a05be3ccae366b9b96e176b51fbe54aab
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tracing/filters: Check perf permissions before resolving .function
2026-10-06 22:51 [PATCH] tracing/filters: Check perf permissions before resolving .function Kyle Zeng
@ 2026-10-07 3:44 ` Masami Hiramatsu
2026-10-07 3:47 ` Kyle Zeng
0 siblings, 1 reply; 5+ messages in thread
From: Masami Hiramatsu @ 2026-10-07 3:44 UTC (permalink / raw)
To: kylebot
Cc: linux-trace-kernel, linux-kernel, rostedt, mhiramat,
outbounddisclosures, Kyle Zeng, stable
On Tue, 06 Oct 2026 15:51:12 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> perf_trace_event_perm() allows tracepoint counters that do not request
> PERF_SAMPLE_RAW without raw tracepoint permissions. A self-targeted,
> disabled event with exclude_kernel=1 can therefore reach the filter
> compiler even at perf_event_paranoid=2.
>
> The .function suffix accepts any field of sizeof(long) and resolves its
> operand through kallsyms_lookup_name() and kallsyms_lookup_size_offset().
> The success or failure of a numeric filter discloses whether an address
> belongs to a known kernel symbol range. On x86-64 this can be used to
> recover the randomized kernel image base. A named filter also exposes
> the resolved symbol range through the counter when the tracepoint field
> is controlled by the caller, as with a syscall argument.
>
> Pass the filter's perf origin to the predicate parser and require
> perf_allow_tracepoint() before resolving a .function operand. This uses
> the same sysctl, initial-namespace capability and LSM policy as raw
> tracepoint access, and closes both the numeric and named-symbol oracles.
> Do not change ordinary perf counting filters or filters created through
> the separately controlled tracefs interfaces.
Good catch!
>
> Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:gpt-6-astra
nit: This should be
Assisted-by: LLM
> Signed-off-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thanks!
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tracing/filters: Check perf permissions before resolving .function
2026-10-07 3:44 ` Masami Hiramatsu
@ 2026-10-07 3:47 ` Kyle Zeng
2026-10-07 5:52 ` Masami Hiramatsu
0 siblings, 1 reply; 5+ messages in thread
From: Kyle Zeng @ 2026-10-07 3:47 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: linux-trace-kernel, linux-kernel, rostedt, outbounddisclosures, stable
On Wed, Oct 07, 2026 at 03:44:20AM +0000, Masami Hiramatsu wrote:
> On Tue, 06 Oct 2026 15:51:12 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> > perf_trace_event_perm() allows tracepoint counters that do not request
> > PERF_SAMPLE_RAW without raw tracepoint permissions. A self-targeted,
> > disabled event with exclude_kernel=1 can therefore reach the filter
> > compiler even at perf_event_paranoid=2.
> >
> > The .function suffix accepts any field of sizeof(long) and resolves its
> > operand through kallsyms_lookup_name() and kallsyms_lookup_size_offset().
> > The success or failure of a numeric filter discloses whether an address
> > belongs to a known kernel symbol range. On x86-64 this can be used to
> > recover the randomized kernel image base. A named filter also exposes
> > the resolved symbol range through the counter when the tracepoint field
> > is controlled by the caller, as with a syscall argument.
> >
> > Pass the filter's perf origin to the predicate parser and require
> > perf_allow_tracepoint() before resolving a .function operand. This uses
> > the same sysctl, initial-namespace capability and LSM policy as raw
> > tracepoint access, and closes both the numeric and named-symbol oracles.
> > Do not change ordinary perf counting filters or filters created through
> > the separately controlled tracefs interfaces.
>
> Good catch!
>
> >
> > Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
> > Cc: stable@vger.kernel.org
> > Assisted-by: Codex:gpt-6-astra
>
> nit: This should be
>
> Assisted-by: LLM
Didn't know there was a change of convention. Should I send in a v2 or
it will be picked up automatically?
Thanks,
Kyle
>
> > Signed-off-by: Kyle Zeng <kylebot@openai.com>
>
> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> Thanks!
>
>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tracing/filters: Check perf permissions before resolving .function
2026-10-07 3:47 ` Kyle Zeng
@ 2026-10-07 5:52 ` Masami Hiramatsu
2026-10-07 5:56 ` Kyle Zeng
0 siblings, 1 reply; 5+ messages in thread
From: Masami Hiramatsu @ 2026-10-07 5:52 UTC (permalink / raw)
To: kylebot
Cc: Masami Hiramatsu, linux-trace-kernel, linux-kernel, rostedt,
outbounddisclosures, stable
On Tue, 06 Oct 2026 20:47:17 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> On Wed, Oct 07, 2026 at 03:44:20AM +0000, Masami Hiramatsu wrote:
> > On Tue, 06 Oct 2026 15:51:12 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> > > perf_trace_event_perm() allows tracepoint counters that do not request
> > > PERF_SAMPLE_RAW without raw tracepoint permissions. A self-targeted,
> > > disabled event with exclude_kernel=1 can therefore reach the filter
> > > compiler even at perf_event_paranoid=2.
> > >
> > > The .function suffix accepts any field of sizeof(long) and resolves its
> > > operand through kallsyms_lookup_name() and kallsyms_lookup_size_offset().
> > > The success or failure of a numeric filter discloses whether an address
> > > belongs to a known kernel symbol range. On x86-64 this can be used to
> > > recover the randomized kernel image base. A named filter also exposes
> > > the resolved symbol range through the counter when the tracepoint field
> > > is controlled by the caller, as with a syscall argument.
> > >
> > > Pass the filter's perf origin to the predicate parser and require
> > > perf_allow_tracepoint() before resolving a .function operand. This uses
> > > the same sysctl, initial-namespace capability and LSM policy as raw
> > > tracepoint access, and closes both the numeric and named-symbol oracles.
> > > Do not change ordinary perf counting filters or filters created through
> > > the separately controlled tracefs interfaces.
> >
> > Good catch!
> >
> > >
> > > Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
> > > Cc: stable@vger.kernel.org
> > > Assisted-by: Codex:gpt-6-astra
> >
> > nit: This should be
> >
> > Assisted-by: LLM
>
> Didn't know there was a change of convention. Should I send in a v2 or
> it will be picked up automatically?
We can change the tag when picking up, so you don't need to resend it only
for tag update. But for this patch, please update according to Sashiko's
comment.
https://lore.kernel.org/all/sashiko-outbox-162502@kernel.org/
Thanks,
>
> Thanks,
> Kyle
>
> >
> > > Signed-off-by: Kyle Zeng <kylebot@openai.com>
> >
> > Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> >
> > Thanks!
> >
> >
> > --
> > Masami Hiramatsu (Google) <mhiramat@kernel.org>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tracing/filters: Check perf permissions before resolving .function
2026-10-07 5:52 ` Masami Hiramatsu
@ 2026-10-07 5:56 ` Kyle Zeng
0 siblings, 0 replies; 5+ messages in thread
From: Kyle Zeng @ 2026-10-07 5:56 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: linux-trace-kernel, linux-kernel, rostedt, outbounddisclosures, stable
On Wed, Oct 07, 2026 at 05:52:22AM +0000, Masami Hiramatsu wrote:
> On Tue, 06 Oct 2026 20:47:17 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> > On Wed, Oct 07, 2026 at 03:44:20AM +0000, Masami Hiramatsu wrote:
> > > On Tue, 06 Oct 2026 15:51:12 -0700, Kyle Zeng <kylebot@openai.com> wrote:
> > > > perf_trace_event_perm() allows tracepoint counters that do not request
> > > > PERF_SAMPLE_RAW without raw tracepoint permissions. A self-targeted,
> > > > disabled event with exclude_kernel=1 can therefore reach the filter
> > > > compiler even at perf_event_paranoid=2.
> > > >
> > > > The .function suffix accepts any field of sizeof(long) and resolves its
> > > > operand through kallsyms_lookup_name() and kallsyms_lookup_size_offset().
> > > > The success or failure of a numeric filter discloses whether an address
> > > > belongs to a known kernel symbol range. On x86-64 this can be used to
> > > > recover the randomized kernel image base. A named filter also exposes
> > > > the resolved symbol range through the counter when the tracepoint field
> > > > is controlled by the caller, as with a syscall argument.
> > > >
> > > > Pass the filter's perf origin to the predicate parser and require
> > > > perf_allow_tracepoint() before resolving a .function operand. This uses
> > > > the same sysctl, initial-namespace capability and LSM policy as raw
> > > > tracepoint access, and closes both the numeric and named-symbol oracles.
> > > > Do not change ordinary perf counting filters or filters created through
> > > > the separately controlled tracefs interfaces.
> > >
> > > Good catch!
> > >
> > > >
> > > > Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
> > > > Cc: stable@vger.kernel.org
> > > > Assisted-by: Codex:gpt-6-astra
> > >
> > > nit: This should be
> > >
> > > Assisted-by: LLM
> >
> > Didn't know there was a change of convention. Should I send in a v2 or
> > it will be picked up automatically?
>
> We can change the tag when picking up, so you don't need to resend it only
> for tag update. But for this patch, please update according to Sashiko's
> comment.
Thanks for the explanation.
I just sent a v2: https://sashiko.dev/#/message/20261007050315.65139-1-kylebot%40openai.com
Best,
Kyle
>
> https://lore.kernel.org/all/sashiko-outbox-162502@kernel.org/
>
> Thanks,
>
> >
> > Thanks,
> > Kyle
> >
> > >
> > > > Signed-off-by: Kyle Zeng <kylebot@openai.com>
> > >
> > > Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> > >
> > > Thanks!
> > >
> > >
> > > --
> > > Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-07 5:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-06 22:51 [PATCH] tracing/filters: Check perf permissions before resolving .function Kyle Zeng
2026-10-07 3:44 ` Masami Hiramatsu
2026-10-07 3:47 ` Kyle Zeng
2026-10-07 5:52 ` Masami Hiramatsu
2026-10-07 5:56 ` Kyle Zeng
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®