All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	 Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>
Cc: 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>, Song Liu <song@kernel.org>,
	 Alexei Starovoitov <ast@kernel.org>,
	linux-perf-users@vger.kernel.org,  linux-kernel@vger.kernel.org,
	bpf@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH v1] perf/core: Restore header fields in sideband output callbacks
Date: Mon, 28 Sep 2026 18:42:06 -0700	[thread overview]
Message-ID: <20260929014206.4175245-1-irogers@google.com> (raw)

perf_iterate_sb() invokes its callback for each matching perf_event on
the CPU and task context, passing a shared caller-allocated event
structure.

perf_event_header__init_id() increments header->size by
event->id_header_size. Unlike perf_event_task_output(),
perf_event_comm_output(), perf_event_namespaces_output(),
perf_event_cgroup_output(), perf_event_mmap_output(), and
perf_callchain_deferred_output(), three sideband callbacks failed to
save and restore header.size around perf_event_header__init_id():
- perf_event_ksymbol_output()
- perf_event_bpf_output()
- perf_event_text_poke_output()

When multiple events with attr.ksymbol, attr.bpf_event, or
attr.text_poke and sample_id_all are active on the same CPU, each
subsequent event receives a record whose header.size is inflated by all
preceding events' id_header_size values while only a single id_sample is
written, leaving uninitialized ring-buffer bytes at the end of the
record and causing userspace perf to fail with -EFAULT ("Bad address")
when parsing the sample_id trailer.

Similarly, perf_event_mmap_output() sets PERF_RECORD_MISC_MMAP_BUILD_ID
in mmap_event->event_id.header.misc when event->attr.build_id is
enabled, but only saved and restored header.size and header.type. If an
event with attr.build_id is followed by an event with attr.mmap2 and
!attr.build_id, the second event receives PERF_RECORD_MISC_MMAP_BUILD_ID
in header.misc while its payload contains maj/min/ino/ino_generation
instead of a build ID.

Save and restore header.size in the ksymbol, bpf, and text_poke output
callbacks, and save and restore header.misc in perf_event_mmap_output().

Fixes: 76193a94522f ("perf, bpf: Introduce PERF_RECORD_KSYMBOL")
Fixes: 6ee52e2a3fe4 ("perf, bpf: Introduce PERF_RECORD_BPF_EVENT")
Fixes: e17d43b93e54 ("perf: Add perf text poke event")
Fixes: 88a16a130933 ("perf: Add build id data in mmap2 event")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 kernel/events/core.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 33210aff3ee6..ea3697295bd4 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -9029,6 +9029,11 @@ static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
  *
  * For new callers; ensure that account_pmu_sb_event() includes
  * your event, otherwise it might not get delivered.
+ *
+ * Note: @data is shared across all @output calls, so any fields modified
+ * incrementally or conditionally (e.g. header.size via
+ * perf_event_header__init_id()) must be saved and restored by @output,
+ * or unconditionally re-initialized on each call.
  */
 static void
 perf_iterate_sb(perf_iterate_f output, void *data,
@@ -9723,6 +9728,7 @@ static void perf_event_mmap_output(struct perf_event *event,
 	struct perf_sample_data sample;
 	int size = mmap_event->event_id.header.size;
 	u32 type = mmap_event->event_id.header.type;
+	u16 misc = mmap_event->event_id.header.misc;
 	bool use_build_id;
 	int ret;
 
@@ -9780,6 +9786,7 @@ static void perf_event_mmap_output(struct perf_event *event,
 out:
 	mmap_event->event_id.header.size = size;
 	mmap_event->event_id.header.type = type;
+	mmap_event->event_id.header.misc = misc;
 }
 
 static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
@@ -10244,6 +10251,7 @@ static void perf_event_ksymbol_output(struct perf_event *event, void *data)
 	struct perf_ksymbol_event *ksymbol_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = ksymbol_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_ksymbol_match(event))
@@ -10254,13 +10262,15 @@ static void perf_event_ksymbol_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				ksymbol_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, ksymbol_event->event_id);
 	__output_copy(&handle, ksymbol_event->name, ksymbol_event->name_len);
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	ksymbol_event->event_id.header.size = header_size;
 }
 
 void perf_event_ksymbol(u16 ksym_type, u64 addr, u32 len, bool unregister,
@@ -10334,6 +10344,7 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 	struct perf_bpf_event *bpf_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = bpf_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_bpf_match(event))
@@ -10344,12 +10355,14 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				bpf_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, bpf_event->event_id);
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	bpf_event->event_id.header.size = header_size;
 }
 
 static void perf_event_bpf_emit_ksymbols(struct bpf_prog *prog,
@@ -10496,6 +10509,7 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	struct perf_text_poke_event *text_poke_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = text_poke_event->event_id.header.size;
 	u64 padding = 0;
 	int ret;
 
@@ -10507,7 +10521,7 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				text_poke_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, text_poke_event->event_id);
 	perf_output_put(&handle, text_poke_event->old_len);
@@ -10522,6 +10536,8 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	text_poke_event->event_id.header.size = header_size;
 }
 
 void perf_event_text_poke(const void *addr, const void *old_bytes,
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


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

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29  1:42 Ian Rogers [this message]
2026-09-29  1:48 ` [PATCH v1] perf/core: Restore header fields in sideband output callbacks sashiko-bot
2026-09-29 12:04 ` Peter Zijlstra
2026-09-29 18:21   ` Ian Rogers
2026-09-29 22:23     ` [PATCH v1] perf/core: Replace perf_event_header__init_id with full header init Ian Rogers
2026-09-29 22:35       ` sashiko-bot
2026-10-01  7:07       ` Peter Zijlstra
2026-10-01 16:45         ` Ian Rogers
2026-10-09 23:30       ` patchwork-bot+netdevbpf
2026-09-29 23:37 ` [PATCH v1] perf/core: Restore header fields in sideband output callbacks bot+bpf-ci

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=20260929014206.4175245-1-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=song@kernel.org \
    --cc=stable@vger.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 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.