All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, namhyung@kernel.org
Cc: adrian.hunter@intel.com, james.clark@linaro.org,
	jolsa@kernel.org,  linux-kernel@vger.kernel.org,
	linux-perf-users@vger.kernel.org,  mingo@redhat.com,
	peterz@infradead.org
Subject: [PATCH v2 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events
Date: Mon, 28 Sep 2026 23:29:29 -0700	[thread overview]
Message-ID: <20260929062937.374137-2-irogers@google.com> (raw)
In-Reply-To: <20260929062937.374137-1-irogers@google.com>

On kernels without the fix ("perf/core: Restore header fields in
sideband output callbacks") to restore event_id.header.size in
perf_event_ksymbol_output(), perf_event_bpf_output(), and
perf_event_text_poke_output(), concurrent perf sessions cause those
sideband records to be emitted with header.size inflated by multiple
id_header_size increments while the single id_sample is written
immediately after the event payload. Indexing backwards from
event->header.size reads uninitialized ring-buffer bytes at the end of
the record, causing evlist__event2evsel() to fail with -EFAULT.

Add evsel__event_size() to clamp the effective size used to locate the
trailing id_sample for PERF_RECORD_KSYMBOL, PERF_RECORD_BPF_EVENT, and
PERF_RECORD_TEXT_POKE to payload + id_hdr_size while leaving
event->header.size intact for advancing the ring-buffer/file stream.

Fixes: 9aa0bfa370b2 ("perf tools: Handle PERF_RECORD_KSYMBOL")
Fixes: 45178a928a4b ("perf tools: Handle PERF_RECORD_BPF_EVENT")
Fixes: 246eba8e9041 ("perf tools: Add support for PERF_RECORD_TEXT_POKE")
Link: https://lore.kernel.org/r/20260929014206.4175245-1-irogers@google.com
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/evlist.c |  6 ++--
 tools/perf/util/evsel.c  | 59 +++++++++++++++++++++++++++++++++++++++-
 tools/perf/util/evsel.h  |  1 +
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 9392d912d254..c2402e4791b6 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -973,13 +973,15 @@ static int evlist__event2id(struct evlist *evlist, union perf_event *event, u64
 	const __u64 *array = event->sample.array;
 	ssize_t n;
 
-	n = (event->header.size - sizeof(event->header)) >> 3;
-
 	if (event->header.type == PERF_RECORD_SAMPLE) {
+		n = (event->header.size - sizeof(event->header)) >> 3;
 		if (evlist__id_pos(evlist) >= n)
 			return -1;
 		*id = array[evlist__id_pos(evlist)];
 	} else {
+		u16 size = evsel__event_size(evlist__first(evlist), event);
+
+		n = (size - sizeof(event->header)) >> 3;
 		if (evlist__is_pos(evlist) > n)
 			return -1;
 		n -= evlist__is_pos(evlist);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3367242c5764..9c5e7510f0c0 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -3216,7 +3216,7 @@ static int perf_evsel__parse_id_sample(const union perf_event *event,
 	const __u64 *array = event->sample.array;
 	bool swapped = evsel->needs_swap;
 	union u64_swap u;
-	int i = ((event->header.size - sizeof(event->header)) / sizeof(u64)) - 1;
+	int i = ((evsel__event_size(evsel, event) - sizeof(event->header)) / sizeof(u64)) - 1;
 
 	if (type & PERF_SAMPLE_IDENTIFIER) {
 		if (i < 0)
@@ -3966,6 +3966,63 @@ u16 evsel__id_hdr_size(const struct evsel *evsel)
 	return size;
 }
 
+/*
+ * Prior to kernel fix, perf_event_ksymbol_output(), perf_event_bpf_output(),
+ * and perf_event_text_poke_output() in kernel/events/core.c did not save and
+ * restore event_id.header.size across perf_iterate_sb() iterations. When
+ * multiple perf_events had attr.ksymbol, attr.bpf_event, or attr.text_poke
+ * enabled, header.size was incremented by id_header_size for each matching
+ * event while only a single id_sample was written immediately after the event
+ * payload. Clamp the effective size used to locate the trailing id_sample to
+ * payload + id_hdr_size so events recorded on unpatched kernels can be parsed
+ * without reading uninitialized ring-buffer bytes.
+ */
+u16 evsel__event_size(const struct evsel *evsel, const union perf_event *event)
+{
+	u16 size = event->header.size;
+	u16 id_hdr_size;
+	size_t payload;
+
+	if (!evsel->core.attr.sample_id_all)
+		return size;
+
+	switch (event->header.type) {
+	case PERF_RECORD_KSYMBOL: {
+		const char *name = event->ksymbol.name;
+		size_t fixed = offsetof(struct perf_record_ksymbol, name);
+		size_t max_len, len;
+
+		if (size <= fixed)
+			return size;
+		max_len = size - fixed;
+		len = strnlen(name, max_len);
+		if (len == max_len)
+			return size;
+		payload = fixed + PERF_ALIGN(len + 1, sizeof(u64));
+		break;
+	}
+	case PERF_RECORD_BPF_EVENT:
+		payload = sizeof(struct perf_record_bpf_event);
+		break;
+	case PERF_RECORD_TEXT_POKE: {
+		size_t fixed = offsetof(struct perf_record_text_poke_event, bytes);
+
+		if (size < fixed)
+			return size;
+		payload = PERF_ALIGN(fixed + (size_t)event->text_poke.old_len +
+				     event->text_poke.new_len, sizeof(u64));
+		break;
+	}
+	default:
+		return size;
+	}
+
+	id_hdr_size = evsel__id_hdr_size(evsel);
+	if (payload + id_hdr_size < size)
+		return payload + id_hdr_size;
+	return size;
+}
+
 #ifdef HAVE_LIBTRACEEVENT
 struct tep_format_field *evsel__field(struct evsel *evsel, const char *name)
 {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 5c5799cee601..174f3414fd3c 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -469,6 +469,7 @@ int evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event,
 				  u64 *timestamp);
 
 u16 evsel__id_hdr_size(const struct evsel *evsel);
+u16 evsel__event_size(const struct evsel *evsel, const union perf_event *event);
 
 static inline struct evsel *evsel__next(struct evsel *evsel)
 {
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


  reply	other threads:[~2026-09-29  6:29 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29  2:19 [PATCH v1 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29  2:19 ` [PATCH v1 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events Ian Rogers
2026-09-29  2:38   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29  2:30   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29  2:25   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 4/9] perf test: Deflake Intel PT Python shell tests under load Ian Rogers
2026-09-29  2:24   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 5/9] perf test: Deflake failed-syscalls " Ian Rogers
2026-09-29  2:25   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29  2:26   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29  2:24   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29  2:24   ` sashiko-bot
2026-09-29  2:19 ` [PATCH v1 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
2026-09-29  2:27   ` sashiko-bot
2026-09-29  6:29 ` [PATCH v2 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29  6:29   ` Ian Rogers [this message]
2026-09-29  6:41     ` [PATCH v2 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events sashiko-bot
2026-09-29  6:29   ` [PATCH v2 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29  6:37     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29  6:37     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 4/9] perf test: Deflake Intel PT Python shell tests under load Ian Rogers
2026-09-29  6:35     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 5/9] perf test: Deflake failed-syscalls " Ian Rogers
2026-09-29  6:34     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29  6:35     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29  6:37     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29  6:37     ` sashiko-bot
2026-09-29  6:29   ` [PATCH v2 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
2026-09-29  6:38     ` sashiko-bot
2026-09-29  6:58   ` [PATCH v3 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29  6:58     ` [PATCH v3 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events Ian Rogers
2026-09-29  7:08       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29  7:06       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29  7:04       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 4/9] perf test: Deflake Intel PT Python shell tests under load Ian Rogers
2026-09-29  7:03       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 5/9] perf test: Deflake failed-syscalls " Ian Rogers
2026-09-29  7:04       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29  7:04       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29  7:05       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29  7:04       ` sashiko-bot
2026-09-29  6:58     ` [PATCH v3 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
2026-09-29  7:06       ` sashiko-bot
2026-09-29 18:44     ` [PATCH v3 0/9] perf python: Follow-up fixes and shell test deflaking Arnaldo Carvalho de Melo

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=20260929062937.374137-2-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.