From: Zhengchuan Liang <zcliangcn@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Ross Zwisler <zwisler@google.com>,
linux-perf-users@vger.kernel.org,
linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org,
Zhengchuan Liang <zcliangcn@gmail.com>
Subject: [PATCH v2 1/1] perf/core: Restrict function predicates in trace event filters
Date: Thu, 1 Oct 2026 16:46:11 -0700 [thread overview]
Message-ID: <e66d86bf790ce51ca865c354a9b7a716c08b552f.1790891867.git.zcliangcn@gmail.com> (raw)
In-Reply-To: <cover.1790891867.git.zcliangcn@gmail.com>
Count-only perf tracepoint events can be opened without tracepoint
permission because they do not expose raw sample data. Their
PERF_EVENT_IOC_SET_FILTER ioctl can still pass filter expressions to the
tracing parser.
A .function operand makes the parser resolve either a numeric kernel
address or a kernel symbol. The ioctl return value can therefore be used
as an oracle to recover the randomized kernel text base.
Trace events marked TRACE_EVENT_FL_CAP_ANY are different: task-local
events may expose their raw fields to unprivileged users. Syscall
tracepoints and uprobes deliberately use this exception, so denying every
filter without tracepoint permission would break their ordinary filters.
Check perf_allow_tracepoint() in perf. If permission is denied, continue
only for a task-attached TRACE_EVENT_FL_CAP_ANY event whose filter does
not contain an unquoted .function postfix. This rejects the predicate
before the tracing parser can resolve either form of operand. The scan
uses the parser's quote rules, so .function inside a string operand
remains an ordinary filter value.
This preserves ordinary filters on task-local events whose fields are
already available to the caller, while non-CAP_ANY filters and kernel
address resolution remain unavailable without tracepoint permission.
Fixes: e6745a4da964 ("tracing: Add a way to filter function addresses to function names")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
---
Changes in v2:
- Keep the entire fix in perf, without modifying kernel/trace/*, as
requested by Steven.
- Preserve ordinary filters for task-local TRACE_EVENT_FL_CAP_ANY events
while rejecting their unquoted .function predicates without tracepoint
permission.
- Reject all filters on other trace events without tracepoint permission.
- Follow the tracing parser's quote rules so .function inside a string
operand remains an ordinary value.
v1: https://lore.kernel.org/all/95d3721fa8d4c7a4577ec14e9d7caec4fd0cefcc.1790553331.git.zcliangcn@gmail.com/
kernel/events/core.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 634d2ccbab82..11db8689ac90 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -12251,6 +12251,33 @@ perf_event_set_addr_filter(struct perf_event *event, char *filter_str)
return ret;
}
+#ifdef CONFIG_EVENT_TRACING
+static bool perf_event_filter_has_function(const char *filter_str)
+{
+ char quote = 0;
+
+ for (; *filter_str; filter_str++) {
+ if (quote) {
+ if (*filter_str == quote)
+ quote = 0;
+ continue;
+ }
+
+ switch (*filter_str) {
+ case '\'':
+ case '"':
+ quote = *filter_str;
+ break;
+ default:
+ if (str_has_prefix(filter_str, ".function"))
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
static int perf_event_set_filter(struct perf_event *event, void __user *arg)
{
int ret = -EINVAL;
@@ -12264,6 +12291,14 @@ static int perf_event_set_filter(struct perf_event *event, void __user *arg)
if (perf_event_is_tracing(event)) {
struct perf_event_context *ctx = event->ctx;
+ ret = perf_allow_tracepoint();
+ if (ret && (!(event->attach_state & PERF_ATTACH_TASK) ||
+ !(event->tp_event->flags & TRACE_EVENT_FL_CAP_ANY) ||
+ perf_event_filter_has_function(filter_str))) {
+ kfree(filter_str);
+ return ret;
+ }
+
/*
* Beware, here be dragons!!
*
--
2.25.1
next prev parent reply other threads:[~2026-10-01 23:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 23:46 [PATCH v2 0/1] perf/core: Prevent tracepoint filters from exposing the kernel text base Zhengchuan Liang
2026-10-01 23:46 ` Zhengchuan Liang [this message]
2026-10-02 9:14 ` [PATCH v2 1/1] perf/core: Restrict function predicates in trace event filters sashiko-bot
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=e66d86bf790ce51ca865c354a9b7a716c08b552f.1790891867.git.zcliangcn@gmail.com \
--to=zcliangcn@gmail.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=zwisler@google.com \
/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