+++ /dev/null
-From fdb3e586c8157e55959c8c0059bb01e7b26b6fdb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 8 Jun 2026 08:10:43 -0300
-Subject: perf bpf: Add NULL check for btf__type_by_id() in
- synthesize_bpf_prog_name()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 903b0526dcf86d030c5970b4b0a67f9c227368e2 ]
-
-synthesize_bpf_prog_name() calls btf__type_by_id() and immediately
-dereferences the result via t->name_off without checking for NULL.
-btf__type_by_id() returns NULL when the type_id is invalid or out
-of range. When processing perf.data files, finfo->type_id comes from
-untrusted input, so an invalid ID causes a NULL pointer dereference.
-
-Fix by checking t for NULL before dereferencing.
-
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Fixes: fc462ac75b36daaa ("perf bpf: Extract logic to create program names from perf_event__synthesize_one_bpf_prog()")
-Cc: Song Liu <songliubraving@fb.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/bpf-event.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
-index d94e523b2cebbb..5a4138cbba89a0 100644
---- a/tools/perf/util/bpf-event.c
-+++ b/tools/perf/util/bpf-event.c
-@@ -201,7 +201,8 @@ static int synthesize_bpf_prog_name(char *buf, int size,
- if (btf) {
- finfo = func_infos + sub_id * info->func_info_rec_size;
- t = btf__type_by_id(btf, finfo->type_id);
-- short_name = btf__name_by_offset(btf, t->name_off);
-+ if (t)
-+ short_name = btf__name_by_offset(btf, t->name_off);
- } else if (sub_id == 0 && sub_prog_cnt == 1) {
- /* no subprog */
- if (info->name[0])
---
-2.53.0
-
+++ /dev/null
-From 9b623ffc5b6fede827fa096ec56d67f86f490fe3 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 10 Jun 2026 21:03:16 -0300
-Subject: perf bpf: Bounds-check array offsets in bpil_offs_to_addr()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 033e85edfbf271f92979d2a39aeaf40f8472a795 ]
-
-bpil_offs_to_addr() converts offsets stored in perf.data's
-bpf_prog_info_linear structure into heap pointers by adding the offset
-to the data allocation base. The offsets come from untrusted file input
-and are not validated against data_len.
-
-If an offset exceeds data_len, the computed address points outside the
-allocated data buffer. Callers like synthesize_bpf_prog_name() then
-dereference prog_tags[sub_id] or func_info pointers, reading arbitrary
-heap memory.
-
-Add a bounds check: when an offset exceeds data_len, zero the field
-and skip the conversion. This prevents out-of-bounds pointer
-construction from crafted perf.data files.
-
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Fixes: 6ac22d036f86c4e2 ("perf bpf: Pull in bpf_program__get_prog_info_linear()")
-Cc: Dave Marchevsky <davemarchevsky@fb.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/bpf-utils.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c
-index 80b1d2b3729ba4..a20ed281bcaf80 100644
---- a/tools/perf/util/bpf-utils.c
-+++ b/tools/perf/util/bpf-utils.c
-@@ -246,6 +246,7 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
- for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) {
- struct bpil_array_desc *desc;
- __u64 addr, offs;
-+ __u32 count, size;
-
- if ((info_linear->arrays & (1UL << i)) == 0)
- continue;
-@@ -253,6 +254,21 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
- desc = bpil_array_desc + i;
- offs = bpf_prog_info_read_offset_u64(&info_linear->info,
- desc->array_offset);
-+ count = bpf_prog_info_read_offset_u32(&info_linear->info,
-+ desc->count_offset);
-+ size = bpf_prog_info_read_offset_u32(&info_linear->info,
-+ desc->size_offset);
-+ /* offset and extent from perf.data are untrusted — keep within data[] */
-+ if (offs >= info_linear->data_len ||
-+ (u64)count * size > info_linear->data_len - offs) {
-+ bpf_prog_info_set_offset_u64(&info_linear->info,
-+ desc->array_offset, 0);
-+ bpf_prog_info_set_offset_u32(&info_linear->info,
-+ desc->count_offset, 0);
-+ /* clear the bit so bpil_addr_to_offs() won't reverse a zeroed address */
-+ info_linear->arrays &= ~(1UL << i);
-+ continue;
-+ }
- addr = offs + ptr_to_u64(info_linear->data);
- bpf_prog_info_set_offset_u64(&info_linear->info,
- desc->array_offset, addr);
---
-2.53.0
-
+++ /dev/null
-From 123fb4adfacaca3fa61823f523397c3956a2a1f0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 14:23:15 -0300
-Subject: perf bpf: Use scnprintf() in snprintf_hex() and
- synthesize_bpf_prog_name()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit cab3a9331ed0b3f884dd61c8a25b3cf123705982 ]
-
-Both functions accumulate formatted output via ret += snprintf(buf + ret,
-size - ret, ...). If the buffer is too small and snprintf() returns more
-than the remaining space, ret exceeds size and the next 'size - ret'
-underflows, causing snprintf() to write past the buffer end.
-
-Switch to scnprintf() which returns the actual number of bytes written,
-making the accumulation safe.
-
-Fixes: 7b612e291a5affb1 ("perf tools: Synthesize PERF_RECORD_* for loaded BPF programs")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Reviewed-by: Ian Rogers <irogers@google.com>
-Cc: Song Liu <song@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/bpf-event.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
-index 91c7bfa82a50a9..d94e523b2cebbb 100644
---- a/tools/perf/util/bpf-event.c
-+++ b/tools/perf/util/bpf-event.c
-@@ -94,7 +94,7 @@ static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len)
- size_t i;
-
- for (i = 0; i < len; i++)
-- ret += snprintf(buf + ret, size - ret, "%02x", data[i]);
-+ ret += scnprintf(buf + ret, size - ret, "%02x", data[i]);
- return ret;
- }
-
-@@ -195,7 +195,7 @@ static int synthesize_bpf_prog_name(char *buf, int size,
- const struct btf_type *t;
- int name_len;
-
-- name_len = snprintf(buf, size, "bpf_prog_");
-+ name_len = scnprintf(buf, size, "bpf_prog_");
- name_len += snprintf_hex(buf + name_len, size - name_len,
- prog_tags[sub_id], BPF_TAG_SIZE);
- if (btf) {
-@@ -208,9 +208,10 @@ static int synthesize_bpf_prog_name(char *buf, int size,
- short_name = info->name;
- } else
- short_name = "F";
-- if (short_name)
-- name_len += snprintf(buf + name_len, size - name_len,
-- "_%s", short_name);
-+ if (short_name) {
-+ name_len += scnprintf(buf + name_len, size - name_len,
-+ "_%s", short_name);
-+ }
- return name_len;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 07d815b1c56ad189953e69d8e47d6f1b275e2351 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 10 Jun 2026 21:01:15 -0300
-Subject: perf bpf: Validate func_info_rec_size and sub_id in
- synthesize_bpf_prog_name()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 10b3c3d63ecc17c6acb855bac5f40367f1115765 ]
-
-synthesize_bpf_prog_name() computes a pointer into the func_info array
-using sub_id * info->func_info_rec_size without validating either value.
-Both come from perf.data and are untrusted:
-
-- A func_info_rec_size smaller than sizeof(struct bpf_func_info) means
- the finfo pointer would reference a truncated entry, reading past it
- into adjacent data.
-
-- A sub_id >= nr_func_info computes an offset past the func_info buffer,
- causing an out-of-bounds read.
-
-Add bounds checks for both values before computing the pointer offset.
-When validation fails, fall through to the non-BTF name path instead
-of reading garbage.
-
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Fixes: 7b612e291a5affb1 ("perf tools: Synthesize PERF_RECORD_* for loaded BPF programs")
-Cc: Song Liu <songliubraving@fb.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/bpf-event.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
-index 5a4138cbba89a0..ec65ad4bc8631a 100644
---- a/tools/perf/util/bpf-event.c
-+++ b/tools/perf/util/bpf-event.c
-@@ -198,7 +198,9 @@ static int synthesize_bpf_prog_name(char *buf, int size,
- name_len = scnprintf(buf, size, "bpf_prog_");
- name_len += snprintf_hex(buf + name_len, size - name_len,
- prog_tags[sub_id], BPF_TAG_SIZE);
-- if (btf) {
-+ if (btf &&
-+ info->func_info_rec_size >= sizeof(*finfo) &&
-+ sub_id < info->nr_func_info) {
- finfo = func_infos + sub_id * info->func_info_rec_size;
- t = btf__type_by_id(btf, finfo->type_id);
- if (t)
---
-2.53.0
-
+++ /dev/null
-From cc73549e4207d695397134690e7e81ab8f12e12a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 6 Jun 2026 11:19:10 -0300
-Subject: perf c2c: Fix use-after-free in he__get_c2c_hists() error path
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 5e5e6196d737c5be03d20647428316b36621608d ]
-
-he__get_c2c_hists() assigns c2c_he->hists before calling
-c2c_hists__init(). If init fails, the error path calls free(hists)
-but leaves c2c_he->hists pointing to freed memory. On teardown,
-c2c_he_free() finds the non-NULL pointer and calls
-hists__delete_entries() on it, causing a use-after-free.
-
-Set c2c_he->hists to NULL before freeing so teardown skips the
-already-freed allocation.
-
-Fixes: b2252ae67b687d2b ("perf c2c report: Decode c2c_stats for hist entries")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-c2c.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
-index a9190458d2d500..bfba131693bed5 100644
---- a/tools/perf/builtin-c2c.c
-+++ b/tools/perf/builtin-c2c.c
-@@ -216,6 +216,7 @@ he__get_c2c_hists(struct hist_entry *he,
-
- ret = c2c_hists__init(hists, sort, nr_header_lines);
- if (ret) {
-+ c2c_he->hists = NULL;
- free(hists);
- return NULL;
- }
---
-2.53.0
-
+++ /dev/null
-From f6f4951c2cf47b7dd924f6539926d68a1b845398 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 9 Jul 2026 23:30:55 +0900
-Subject: perf/core: Detach event groups during remove_on_exec
-
-From: Taeyang Lee <0wn@theori.io>
-
-[ Upstream commit 037a3c43edfb597665dd34457cd22b14692f2ba3 ]
-
-perf_event_remove_on_exec() removes events by calling
-perf_event_exit_event(). For top-level events, this removes the event from
-the context with DETACH_EXIT only.
-
-This can leave inconsistent group state when a removed event is a group
-leader and the group contains siblings without remove_on_exec. If the group
-was active, the surviving siblings can remain active and attached to the
-removed leader's sibling list, but are no longer represented by a valid
-group leader on the PMU context active lists.
-
-A later close of the removed leader uses DETACH_GROUP and can promote the
-still-active siblings from this stale group state. The next schedule-in can
-then add an already-linked active_list entry again, corrupting the PMU
-context active list.
-
-With DEBUG_LIST enabled, this is caught as a list_add double-add in
-merge_sched_in().
-
-Fix this by detaching group relationships when remove_on_exec removes an
-event. This preserves the existing task-exit and revoke behavior, while
-ensuring surviving siblings are ungrouped before the removed event leaves
-the context.
-
-Fixes: 2e498d0a74e5 ("perf: Add support for event removal on exec")
-Signed-off-by: Taeyang Lee <0wn@theori.io>
-Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-Link: https://patch.msgid.link/ai65GgZcC0LAlWLG@Taeyangs-MacBook-Pro.local
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/events/core.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/kernel/events/core.c b/kernel/events/core.c
-index 146b37e97832a9..1478bad56e40a1 100644
---- a/kernel/events/core.c
-+++ b/kernel/events/core.c
-@@ -4334,7 +4334,8 @@ static void perf_event_enable_on_exec(int ctxn)
-
- static void perf_remove_from_owner(struct perf_event *event);
- static void perf_event_exit_event(struct perf_event *event,
-- struct perf_event_context *ctx);
-+ struct perf_event_context *ctx,
-+ unsigned long detach_flags);
-
- /*
- * Removes all events from the current task that have been marked
-@@ -4365,7 +4366,7 @@ static void perf_event_remove_on_exec(int ctxn)
-
- modified = true;
-
-- perf_event_exit_event(event, ctx);
-+ perf_event_exit_event(event, ctx, DETACH_GROUP);
- }
-
- raw_spin_lock_irqsave(&ctx->lock, flags);
-@@ -13055,10 +13056,11 @@ static void sync_child_event(struct perf_event *child_event)
- }
-
- static void
--perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
-+perf_event_exit_event(struct perf_event *event,
-+ struct perf_event_context *ctx,
-+ unsigned long detach_flags)
- {
- struct perf_event *parent_event = event->parent;
-- unsigned long detach_flags = 0;
-
- if (parent_event) {
- /*
-@@ -13073,7 +13075,7 @@ perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
- * Do destroy all inherited groups, we don't care about those
- * and being thorough is better.
- */
-- detach_flags = DETACH_GROUP | DETACH_CHILD;
-+ detach_flags |= DETACH_GROUP | DETACH_CHILD;
- mutex_lock(&parent_event->child_mutex);
- }
-
-@@ -13158,7 +13160,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
- perf_event_task(child, child_ctx, 0);
-
- list_for_each_entry_safe(child_event, next, &child_ctx->event_list, event_entry)
-- perf_event_exit_event(child_event, child_ctx);
-+ perf_event_exit_event(child_event, child_ctx, 0);
-
- mutex_unlock(&child_ctx->mutex);
-
---
-2.53.0
-
+++ /dev/null
-From 33a394da37512da79356256aec2c994b16b786a1 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 28 May 2026 14:23:55 +0800
-Subject: perf: Fix off-by-one stack buffer overflow in kallsyms__parse()
-
-From: Rui Qi <qirui.001@bytedance.com>
-
-[ Upstream commit 68018df3f55eba96a20dd703f5f276a6518f4963 ]
-
-In kallsyms__parse(), the loop reading symbol names iterates with i <
-sizeof(symbol_name), which allows i to reach sizeof(symbol_name) upon
-loop exit. The subsequent symbol_name[i] = '\0' then writes one byte
-past the end of the stack-allocated symbol_name[] array.
-
-Fix this by changing the loop bound to KSYM_NAME_LEN, so the null
-terminator always lands within the array. The overflow is triggerable by
-a kallsyms entry with a symbol name of KSYM_NAME_LEN+1 or more
-characters (e.g., long Rust mangled names or a malicious
-/proc/kallsyms).
-
-Fixes: 53df2b9344128984 ("libsymbols kallsyms: Parse using io api")
-Signed-off-by: Rui Qi <qirui.001@bytedance.com>
-Acked-by: Namhyung Kim <namhyung@kernel.org>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-Cc: Ian Rogers <irogers@google.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/lib/symbol/kallsyms.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
-index e335ac2b9e1972..d64bd9cc82a90e 100644
---- a/tools/lib/symbol/kallsyms.c
-+++ b/tools/lib/symbol/kallsyms.c
-@@ -60,7 +60,7 @@ int kallsyms__parse(const char *filename, void *arg,
- read_to_eol(&io);
- continue;
- }
-- for (i = 0; i < sizeof(symbol_name); i++) {
-+ for (i = 0; i < KSYM_NAME_LEN; i++) {
- ch = io__get_char(&io);
- if (ch < 0 || ch == '\n')
- break;
-@@ -68,6 +68,9 @@ int kallsyms__parse(const char *filename, void *arg,
- }
- symbol_name[i] = '\0';
-
-+ if (i == KSYM_NAME_LEN)
-+ read_to_eol(&io);
-+
- err = process_symbol(arg, symbol_name, symbol_type, start);
- if (err)
- break;
---
-2.53.0
-
+++ /dev/null
-From 215b2ef5681f6169b43b59797f6b6d877f09cbb3 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 2 May 2026 14:37:39 -0300
-Subject: perf header: Sanity check HEADER_EVENT_DESC attr.size before swap
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 944f65c8b8231d26d4db6be67bcb641142603cb4 ]
-
-read_event_desc() reads nre (event count), sz (attr size), and nr
-(IDs per event) from the file and uses them to control allocations
-and loops without validating them against the section size.
-
-A crafted perf.data could trigger large allocations or many loop
-iterations before __do_read() eventually rejects the reads.
-
-Add bounds checks in read_event_desc():
-- Reject sz smaller than PERF_ATTR_SIZE_VER0.
-- Require at least one event (nre > 0).
-- Check that nre events fit in the remaining section, using the
- minimum per-event footprint of sz + sizeof(u32).
-- Pre-swap attr->size to native byte order, then reject values
- below PERF_ATTR_SIZE_VER0 or above sz before calling
- perf_event__attr_swap() to prevent heap out-of-bounds access.
-- Handle ABI0 (attr.size == 0): substitute PERF_ATTR_SIZE_VER0,
- and on native-endian files write the value back so
- free_event_desc() does not treat the zero as its end-of-array
- sentinel (it iterates while attr.size != 0). The swap path
- skips the write-back — perf_event__attr_swap() has its own
- ABI0 fallback that sets VER0 after swapping.
-- Check that nr IDs fit in the remaining section before allocating.
-
-Fixes: b30b61729246 ("perf tools: Fix a problem when opening old perf.data with different byte order")
-Reported-by: sashiko-bot@kernel.org # Running on a local machine
-Reviewed-by: Ian Rogers <irogers@google.com>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Cc: Wang Nan <wangnan0@huawei.com>
-Assisted-by: Claude:claude-opus-4.6-1m
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/header.c | 54 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 54 insertions(+)
-
-diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
-index b2b0293567f07a..085994cba3895f 100644
---- a/tools/perf/util/header.c
-+++ b/tools/perf/util/header.c
-@@ -1900,9 +1900,28 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
- if (do_read_u32(ff, &nre))
- goto error;
-
-+ /* Size of each of the nre attributes. */
- if (do_read_u32(ff, &sz))
- goto error;
-
-+ /*
-+ * Require at least one event with an attr no smaller than the
-+ * first published struct, and reject sz values where
-+ * sz + sizeof(u32) would overflow size_t (possible on 32-bit)
-+ * or nre == UINT32_MAX where nre + 1 wraps to 0 in the calloc.
-+ *
-+ * The minimum section footprint per event is sz bytes for the
-+ * attr plus a u32 for the id count, check that nre events fit.
-+ */
-+ if (!nre || sz < PERF_ATTR_SIZE_VER0 ||
-+ sz > ff->size || (size_t)sz > SIZE_MAX - sizeof(u32) ||
-+ nre == UINT32_MAX ||
-+ nre > (ff->size - ff->offset) / (sz + sizeof(u32))) {
-+ pr_err("Invalid HEADER_EVENT_DESC: nre=%u sz=%u (min %d)\n",
-+ nre, sz, PERF_ATTR_SIZE_VER0);
-+ goto error;
-+ }
-+
- /* buffer to hold on file attr struct */
- buf = malloc(sz);
- if (!buf)
-@@ -1918,6 +1937,9 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
- msz = sz;
-
- for (i = 0, evsel = events; i < nre; evsel++, i++) {
-+ struct perf_event_attr *attr = buf;
-+ u32 attr_size;
-+
- evsel->core.idx = i;
-
- /*
-@@ -1927,6 +1949,32 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
- if (__do_read(ff, buf, sz))
- goto error;
-
-+ /* Reject before attr_swap to prevent OOB via bswap_safe() */
-+ attr_size = ff->ph->needs_swap ? bswap_32(attr->size) : attr->size;
-+ /* ABI0: size == 0 means the producer didn't set it */
-+ if (!attr_size) {
-+ attr_size = PERF_ATTR_SIZE_VER0;
-+ /*
-+ * Write back so free_event_desc() doesn't
-+ * treat this event as the end-of-array sentinel
-+ * (it iterates while attr.size != 0).
-+ *
-+ * Only for native — the swap path must NOT
-+ * write native-endian VER0 here because
-+ * perf_event__attr_swap() would re-swap it
-+ * to 0x40000000, defeating bswap_safe() bounds.
-+ * perf_event__attr_swap() has its own ABI0
-+ * fallback that sets VER0 after swapping.
-+ */
-+ if (!ff->ph->needs_swap)
-+ attr->size = attr_size;
-+ }
-+ if (attr_size < PERF_ATTR_SIZE_VER0 || attr_size > sz) {
-+ pr_err("Event %d attr.size (%u) invalid (min: %d, max: %u)\n",
-+ i, attr_size, PERF_ATTR_SIZE_VER0, sz);
-+ goto error;
-+ }
-+
- if (ff->ph->needs_swap)
- perf_event__attr_swap(buf);
-
-@@ -1948,6 +1996,12 @@ static struct evsel *read_event_desc(struct feat_fd *ff)
- if (!nr)
- continue;
-
-+ /* Prevent oversized allocation from crafted nr */
-+ if (nr > (ff->size - ff->offset) / sizeof(*id)) {
-+ pr_err("Event %d: id count %u exceeds remaining section\n", i, nr);
-+ goto error;
-+ }
-+
- id = calloc(nr, sizeof(*id));
- if (!id)
- goto error;
---
-2.53.0
-
+++ /dev/null
-From afb60f47b8c126fb47dc0b614a657cfbb31ed02b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 14:35:28 -0300
-Subject: perf hists: Fix snprintf() in hists__scnprintf_title() UID filter
- path
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 227a8748742f0263f1fe3131449b44563b77a209 ]
-
-hists__scnprintf_title() accumulates formatted output into a buffer
-using scnprintf() for all filter clauses except the UID filter, which
-uses snprintf(). If the buffer fills up and snprintf() returns more
-than the remaining space, printed exceeds size and the next 'size -
-printed' underflows, causing later scnprintf() calls to write past
-the buffer.
-
-Switch the UID filter clause to scnprintf() to match the rest of the
-function.
-
-Fixes: 25c312dbf88ca402 ("perf hists: Move hists__scnprintf_title() away from the TUI code")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Reviewed-by: Ian Rogers <irogers@google.com>
-Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/hist.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
-index 2e7977a8ca559b..36bb336b406fb6 100644
---- a/tools/perf/util/hist.c
-+++ b/tools/perf/util/hist.c
-@@ -2769,9 +2769,10 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh
- ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
-
-
-- if (hists->uid_filter_str)
-- printed += snprintf(bf + printed, size - printed,
-- ", UID: %s", hists->uid_filter_str);
-+ if (hists->uid_filter_str) {
-+ printed += scnprintf(bf + printed, size - printed,
-+ ", UID: %s", hists->uid_filter_str);
-+ }
- if (thread) {
- if (hists__has(hists, thread)) {
- printed += scnprintf(bf + printed, size - printed,
---
-2.53.0
-
+++ /dev/null
-From 38d0ffc81d4280aa09312d5dccf159bf6f22fbad Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 21:06:54 -0300
-Subject: perf intel-pt: Fix snprintf size tracking bug in insn decoder
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit b6bb3b005dcdd960b8e0b7f9d6869132b3de08d5 ]
-
-dump_insn() tracks remaining buffer space with a 'left' variable,
-but the loop subtracts the cumulative offset 'n' each iteration
-instead of just the per-iteration delta:
-
- n += snprintf(x->out + n, left, "%02x ", inbuf[i]);
- left -= n; /* BUG: n is cumulative, not the delta */
-
-After two iterations left goes massively negative, wrapping to a
-huge value when passed as size_t to snprintf(), disabling all bounds
-checking for the rest of the loop.
-
-Switch to scnprintf() accumulation using sizeof(x->out) - n as the
-remaining space, which is always correct and eliminates the separate
-'left' variable entirely.
-
-Fixes: 48d02a1d5c137d36 ("perf script: Add 'brstackinsn' for branch stacks")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Andi Kleen <ak@linux.intel.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- .../util/intel-pt-decoder/intel-pt-insn-decoder.c | 11 +++--------
- 1 file changed, 3 insertions(+), 8 deletions(-)
-
-diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
-index 1376077183f720..4e1b92f6534b42 100644
---- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
-+++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
-@@ -198,7 +198,6 @@ const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused,
- {
- struct insn insn;
- int n, i, ret;
-- int left;
-
- ret = insn_decode(&insn, inbuf, inlen,
- x->is64bit ? INSN_MODE_64 : INSN_MODE_32);
-@@ -207,13 +206,9 @@ const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused,
- return "<bad>";
- if (lenp)
- *lenp = insn.length;
-- left = sizeof(x->out);
-- n = snprintf(x->out, left, "insn: ");
-- left -= n;
-- for (i = 0; i < insn.length; i++) {
-- n += snprintf(x->out + n, left, "%02x ", inbuf[i]);
-- left -= n;
-- }
-+ n = scnprintf(x->out, sizeof(x->out), "insn: ");
-+ for (i = 0; i < insn.length; i++)
-+ n += scnprintf(x->out + n, sizeof(x->out) - n, "%02x ", inbuf[i]);
- return x->out;
- }
-
---
-2.53.0
-
+++ /dev/null
-From befc8d251cffa7ddfb395dbcb98d087fcfb26c25 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 13 Jun 2026 13:59:39 -0300
-Subject: perf machine: Use snprintf() for guestmount path construction
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit fe63d3bca288c5bb983304efd5fc3a5ff3183403 ]
-
-machines__findnew() and machines__create_guest_kernel_maps() use
-sprintf() to build paths by prepending symbol_conf.guestmount.
-Both write into PATH_MAX stack buffers, but guestmount comes from
-user configuration and is not length-checked. A guestmount path
-at or near PATH_MAX causes a stack buffer overflow.
-
-Switch to snprintf() with sizeof() to prevent overflow. The
-subsequent access()/fopen() calls will fail on a truncated path.
-
-Fixes: a1645ce12adb6c9c ("perf: 'perf kvm' tool for monitoring guest performance from host")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/machine.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
-index 419147da8d672b..41137c7b4cdacc 100644
---- a/tools/perf/util/machine.c
-+++ b/tools/perf/util/machine.c
-@@ -362,7 +362,7 @@ struct machine *machines__findnew(struct machines *machines, pid_t pid)
- if ((pid != HOST_KERNEL_ID) &&
- (pid != DEFAULT_GUEST_KERNEL_ID) &&
- (symbol_conf.guestmount)) {
-- sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
-+ snprintf(path, sizeof(path), "%s/%d", symbol_conf.guestmount, pid);
- if (access(path, R_OK)) {
- static struct strlist *seen;
-
-@@ -1365,9 +1365,9 @@ int machines__create_guest_kernel_maps(struct machines *machines)
- namelist[i]->d_name);
- continue;
- }
-- sprintf(path, "%s/%s/proc/kallsyms",
-- symbol_conf.guestmount,
-- namelist[i]->d_name);
-+ snprintf(path, sizeof(path), "%s/%s/proc/kallsyms",
-+ symbol_conf.guestmount,
-+ namelist[i]->d_name);
- ret = access(path, R_OK);
- if (ret) {
- pr_debug("Can't access file %s\n", path);
---
-2.53.0
-
+++ /dev/null
-From 600b4df837c2de0de4966e280bca0584b8cebe32 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 6 Jun 2026 11:03:29 -0300
-Subject: perf mmap: Fix NULL deref in aio cleanup on alloc failure
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 25627346b10e6a564610ea2c49dc6dd54812226d ]
-
-perf_mmap__aio_mmap() sets map->aio.nr_cblocks before allocating the
-data array. If calloc() for aiocb or cblocks fails before the data
-array is allocated, the return -1 path leads to perf_mmap__aio_munmap()
-which loops nr_cblocks times calling perf_mmap__aio_free(). Both
-versions of perf_mmap__aio_free() (NUMA and non-NUMA) dereference
-map->aio.data[idx] without checking if data is NULL, causing a NULL
-pointer dereference.
-
-Add NULL checks for map->aio.data at the top of both
-perf_mmap__aio_free() variants so the cleanup path is safe when
-allocation fails partway through perf_mmap__aio_mmap().
-
-Fixes: d3d1af6f011a553a ("perf record: Enable asynchronous trace writing")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/mmap.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
-index 63d8a05e60544a..adc2ee6eeb8e26 100644
---- a/tools/perf/util/mmap.c
-+++ b/tools/perf/util/mmap.c
-@@ -88,10 +88,10 @@ static int perf_mmap__aio_alloc(struct mmap *map, int idx)
-
- static void perf_mmap__aio_free(struct mmap *map, int idx)
- {
-- if (map->aio.data[idx]) {
-- munmap(map->aio.data[idx], mmap__mmap_len(map));
-- map->aio.data[idx] = NULL;
-- }
-+ if (!map->aio.data || !map->aio.data[idx])
-+ return;
-+ munmap(map->aio.data[idx], mmap__mmap_len(map));
-+ map->aio.data[idx] = NULL;
- }
-
- static int perf_mmap__aio_bind(struct mmap *map, int idx, struct perf_cpu cpu, int affinity)
-@@ -140,6 +140,8 @@ static int perf_mmap__aio_alloc(struct mmap *map, int idx)
-
- static void perf_mmap__aio_free(struct mmap *map, int idx)
- {
-+ if (!map->aio.data)
-+ return;
- zfree(&(map->aio.data[idx]));
- }
-
---
-2.53.0
-
+++ /dev/null
-From df8d5b14fd731450e4d2a378f2cf71c560c6d1c0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 5 Jun 2026 10:56:33 -0300
-Subject: perf mmap: Guard cpu__get_node() return in aio_bind()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit f32dc302a090f48893477ef297a888db109ec0bd ]
-
-perf_mmap__aio_bind() passes the cpu__get_node() return value directly
-to an unsigned long variable (node_index). When cpu__get_node() returns
--1 for an unknown CPU, the implicit int-to-unsigned-long conversion
-sign-extends it to ULONG_MAX.
-
-This causes bitmap_zalloc(ULONG_MAX + 1) which wraps to
-bitmap_zalloc(0), returning a zero-sized allocation. The subsequent
-__set_bit(ULONG_MAX, node_mask) then writes massively out of bounds.
-
-Check the return value in a signed temporary before assigning to
-node_index, and skip the NUMA binding when the node is unknown.
-
-Fixes: c44a8b44ca9f ("perf record: Bind the AIO user space buffers to nodes")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/mmap.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
-index a4dff881be39b6..63d8a05e60544a 100644
---- a/tools/perf/util/mmap.c
-+++ b/tools/perf/util/mmap.c
-@@ -103,9 +103,15 @@ static int perf_mmap__aio_bind(struct mmap *map, int idx, struct perf_cpu cpu, i
- int err = 0;
-
- if (affinity != PERF_AFFINITY_SYS && cpu__max_node() > 1) {
-+ int node;
-+
- data = map->aio.data[idx];
- mmap_len = mmap__mmap_len(map);
-- node_index = cpu__get_node(cpu);
-+ node = cpu__get_node(cpu);
-+ /* -1 sign-extends to ULONG_MAX, wrapping bitmap_zalloc(0) and OOB __set_bit */
-+ if (node < 0)
-+ return 0;
-+ node_index = node;
- node_mask = bitmap_zalloc(node_index + 1);
- if (!node_mask) {
- pr_err("Failed to allocate node mask for mbind: error %m\n");
---
-2.53.0
-
+++ /dev/null
-From 3eb79ba32caa64ad43193cdb083a2c8ad2ae0b3b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 21:03:13 -0300
-Subject: perf pmu: Fix perf_pmu__parse_scale/unit() OOB access on empty sysfs
- file
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 33035f7dd4e49f3f117e70c5e36c8c1ae88d37f2 ]
-
-perf_pmu__parse_scale() reads a PMU scale file then accesses
-scale[sret - 1] to strip a trailing newline. Only sret < 0 is
-guarded, so an empty file (sret == 0) causes scale[-1] — a stack
-buffer underflow that reads and potentially writes out of bounds.
-
-perf_pmu__parse_unit() has the same pattern: alias->unit[sret - 1]
-with sret == 0 accesses the byte before the struct member, which
-may corrupt the adjacent pmu_name pointer field.
-
-Change both guards from sret < 0 to sret <= 0 so that empty files
-are treated as read errors.
-
-Fixes: 410136f5dd96b601 ("tools/perf/stat: Add event unit and scale support")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Stephane Eranian <eranian@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/pmu.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
-index 6761a208c0d9e9..db1418c9369651 100644
---- a/tools/perf/util/pmu.c
-+++ b/tools/perf/util/pmu.c
-@@ -162,7 +162,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
- goto error;
-
- sret = read(fd, scale, sizeof(scale)-1);
-- if (sret < 0)
-+ if (sret <= 0)
- goto error;
-
- if (scale[sret - 1] == '\n')
-@@ -189,7 +189,7 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *n
- return -1;
-
- sret = read(fd, alias->unit, UNIT_MAX_LEN);
-- if (sret < 0)
-+ if (sret <= 0)
- goto error;
-
- close(fd);
---
-2.53.0
-
+++ /dev/null
-From e0bf4d9988c0d91fa31e12974149f1ce30ef2d31 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 21:01:43 -0300
-Subject: perf pmu: Fix pmu_id() heap underwrite on empty identifier file
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 836455e6dbd34eb3d12eeab5e2d2b9a7f1512459 ]
-
-pmu_id() calls filename__read_str() then strips the trailing newline
-via str[len - 1] = 0. If the PMU identifier file is empty,
-filename__read_str() succeeds with len = 0. len - 1 underflows
-size_t to SIZE_MAX, writing a null byte before the heap allocation.
-
-Add a len == 0 check before the newline stripping.
-
-Fixes: 51d548471510843e ("perf pmu: Add pmu_id()")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: John Garry <john.g.garry@oracle.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/pmu.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
-index 9a762c0cc53ce6..6761a208c0d9e9 100644
---- a/tools/perf/util/pmu.c
-+++ b/tools/perf/util/pmu.c
-@@ -666,6 +666,12 @@ static char *pmu_id(const char *name)
- if (sysfs__read_str(path, &str, &len) < 0)
- return NULL;
-
-+ /* empty identifier file — nothing useful */
-+ if (len == 0) {
-+ free(str);
-+ return NULL;
-+ }
-+
- str[len - 1] = 0; /* remove line feed */
-
- return str;
---
-2.53.0
-
+++ /dev/null
-From dbe772472b469958cb8d1b2357b9e5ca59824f41 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 5 May 2026 17:45:42 -0700
-Subject: perf sched: Add missing mmap2 handler in timehist
-
-From: Ian Rogers <irogers@google.com>
-
-[ Upstream commit 91182741369b261c441e63e6678893032a6d7e4c ]
-
-perf_sched__timehist() registers event handlers for options using the
-sched->tool struct. It registers handlers for MMAP, COMM, EXIT, FORK, etc.
-but completely omits registering a handler for MMAP2 events.
-
-Failing to register both MMAP and MMAP2 handlers causes modern systems
-(which primarily output MMAP2 records) to silently drop VMA map mappings.
-This results in uninitialized machine/thread mapping structures, making it
-impossible to resolve shared library instruction pointers (IPs) to dynamic
-symbols/DSOs during timehist callchain analysis.
-
-Fix this by correctly registering perf_event__process_mmap2 in
-sched->tool inside perf_sched__timehist().
-
-Fixes: 49394a2a24c78ce0 ("perf sched timehist: Introduce timehist command")
-Assisted-by: Gemini-CLI:Google Gemini 3
-Signed-off-by: Ian Rogers <irogers@google.com>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: David Ahern <dsahern@gmail.com>
-Cc: Gabriel Marin <gmx@google.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 3ffb41fa82b814..6584e39b2a8d48 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -3055,6 +3055,7 @@ static int perf_sched__timehist(struct perf_sched *sched)
- */
- sched->tool.sample = perf_timehist__process_sample;
- sched->tool.mmap = perf_event__process_mmap;
-+ sched->tool.mmap2 = perf_event__process_mmap2;
- sched->tool.comm = perf_event__process_comm;
- sched->tool.exit = perf_event__process_exit;
- sched->tool.fork = perf_event__process_fork;
---
-2.53.0
-
+++ /dev/null
-From 5a592e91047ba6163fc5af0e4d1c85b255fcabf8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 5 Jun 2026 11:12:08 -0300
-Subject: perf sched: Clean up idle_threads entry on init failure
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit cda5a94ad9181cd60cbf04be11d524201bf489a2 ]
-
-get_idle_thread() allocates a thread via thread__new() and stores it in
-idle_threads[cpu], then calls init_idle_thread() to set up the private
-data. If init_idle_thread() fails (e.g. OOM for the idle_thread_runtime
-struct), the function returns NULL but leaves the partially initialized
-thread in idle_threads[cpu].
-
-On subsequent calls for the same CPU, get_idle_thread() finds a non-NULL
-idle_threads[cpu], skips allocation, and returns thread__get() on a
-thread that has no priv data. Callers then get a thread whose
-thread__priv() returns NULL, leading to unexpected behavior.
-
-Release the thread and reset the slot to NULL on init failure so the
-entry doesn't persist in a corrupted state.
-
-Fixes: 49394a2a24c7 ("perf sched timehist: Introduce timehist command")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: David Ahern <dsahern@gmail.com>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 927c0ece3a074f..167532c7adf006 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -2349,8 +2349,11 @@ static struct thread *get_idle_thread(int cpu)
- idle_threads[cpu] = thread__new(0, 0);
-
- if (idle_threads[cpu]) {
-- if (init_idle_thread(idle_threads[cpu]) < 0)
-+ if (init_idle_thread(idle_threads[cpu]) < 0) {
-+ /* clean up so next call doesn't find a half-initialized thread */
-+ thread__zput(idle_threads[cpu]);
- return NULL;
-+ }
- }
- }
-
---
-2.53.0
-
+++ /dev/null
-From bf9cde1cf1ca7e2c70fba7811f0e365f3518352f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 6 Jun 2026 21:49:16 -0300
-Subject: perf sched: Fix idle-hist callchain display using wrong rb_first
- variant
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit d9b99dc8148e0c1f5da3942131b47e0d21187a32 ]
-
-timehist_print_idlehist_callchain() calls rb_first_cached() on
-sorted_root, but the sort function (callchain_param.sort) populates it
-via rb_insert_color() on the plain rb_root member — not the cached
-variant. This means rb_leftmost is never set, so rb_first_cached()
-always returns NULL and the entire callchain summary is silently
-dropped from --idle-hist output.
-
-The original code in ba957ebb54893aca ("perf sched timehist: Show
-callchains for idle stat") was correct — it used struct rb_root and
-rb_first(). The bug was introduced when sorted_root was converted to
-rb_root_cached without converting the sort insertion path to use
-rb_insert_color_cached().
-
-Use rb_first(&root->rb_root) to match how the tree was populated.
-
-Fixes: cb4c13a5137766c3 ("perf sched: Use cached rbtrees")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Davidlohr Bueso <dave@stgolabs.net>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Acked-by: Ian Rogers <irogers@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 9fa02e8ab091c0..84f705a2286d11 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -2890,7 +2890,8 @@ static size_t timehist_print_idlehist_callchain(struct rb_root_cached *root)
- size_t ret = 0;
- FILE *fp = stdout;
- struct callchain_node *chain;
-- struct rb_node *rb_node = rb_first_cached(root);
-+ /* sort() uses rb_insert_color() on rb_root, not rb_root_cached */
-+ struct rb_node *rb_node = rb_first(&root->rb_root);
-
- printf(" %16s %8s %s\n", "Idle time (msec)", "Count", "Callchains");
- printf(" %.16s %.8s %.50s\n", graph_dotted_line, graph_dotted_line,
---
-2.53.0
-
+++ /dev/null
-From 7793b602d04187ff7e4eb5ef0e2c9a61e8378ab2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 4 Jun 2026 12:56:02 -0300
-Subject: perf sched: Fix NULL dereference in latency_runtime_event
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 8cbca8a480e15f6326ce94287570993f27a4b2d5 ]
-
-latency_runtime_event() passes the return value of
-machine__findnew_thread() directly to thread_atoms_search() at line
-1216, before checking for NULL at line 1220. thread_atoms_search()
-calls pid_cmp() which dereferences the thread pointer via
-thread__tid(), causing a NULL pointer dereference if the allocation
-fails.
-
-All other callers of thread_atoms_search() in this file
-(latency_switch_event, latency_wakeup_event,
-latency_migrate_task_event) correctly check for NULL first.
-
-Move the atoms assignment after the NULL check to match the pattern
-used by the other callers.
-
-Fixes: b91fc39f4ad7 ("perf machine: Protect the machine->threads with a rwlock")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 2c954de3ed419c..927c0ece3a074f 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -1223,13 +1223,15 @@ static int latency_runtime_event(struct perf_sched *sched,
- const u32 pid = evsel__intval(evsel, sample, "pid");
- const u64 runtime = evsel__intval(evsel, sample, "runtime");
- struct thread *thread = machine__findnew_thread(machine, -1, pid);
-- struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
-+ struct work_atoms *atoms;
- u64 timestamp = sample->time;
- int cpu = sample->cpu, err = -1;
-
- if (thread == NULL)
- return -1;
-
-+ atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
-+
- /* perf.data is untrusted input — CPU may be absent or corrupted */
- if (cpu >= MAX_CPUS || cpu < 0) {
- pr_warning("WARNING: at offset %#" PRIx64 ": out-of-bound sample CPU %d, skipping sample\n",
---
-2.53.0
-
+++ /dev/null
-From cb634c99b5760fcaed65970c3d02a7e28421d2f8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 5 Jun 2026 11:26:28 -0300
-Subject: perf sched: Replace BUG_ON and add NULL checks in replay event
- helpers
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 75eafe4a3a93a0143a20c0cc286bfb9008ac1478 ]
-
-get_new_event() has three issues:
-
-1. The zalloc() result is dereferenced without a NULL check, crashing
- on allocation failure.
-
-2. BUG_ON(!task->atoms) kills the process when realloc() fails.
- Since perf.data is untrusted input, this should be a graceful error.
-
-3. The realloc pattern assigns directly to task->atoms, losing the old
- pointer on failure. task->nr_events is also incremented before the
- realloc, leaving corrupted state on failure.
-
-Fix get_new_event() to:
- - Check the zalloc() result before dereferencing
- - Use a temporary for realloc() to avoid losing the old pointer
- - Increment nr_events only after successful realloc
- - Return NULL instead of calling BUG_ON on failure
-
-Also fix add_sched_event_wakeup() where zalloc() for wait_sem is
-passed to sem_init() without a NULL check.
-
-Update all callers (add_sched_event_run, add_sched_event_wakeup,
-add_sched_event_sleep) to handle NULL returns by returning early.
-The replay may produce incomplete output on OOM but will not crash.
-
-Fixes: ec156764d424 ("perf sched: Import schedbench.c")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Ingo Molnar <mingo@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 28 +++++++++++++++++++++++++---
- 1 file changed, 25 insertions(+), 3 deletions(-)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 167532c7adf006..9fa02e8ab091c0 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -363,14 +363,25 @@ get_new_event(struct task_desc *task, u64 timestamp)
- struct sched_atom *event = zalloc(sizeof(*event));
- unsigned long idx = task->nr_events;
- size_t size;
-+ struct sched_atom **atoms_p;
-+
-+ if (event == NULL) {
-+ pr_err("ERROR: sched: failed to allocate event\n");
-+ return NULL;
-+ }
-
- event->timestamp = timestamp;
- event->nr = idx;
-
-+ size = sizeof(struct sched_atom *) * (task->nr_events + 1);
-+ atoms_p = realloc(task->atoms, size);
-+ if (!atoms_p) {
-+ pr_err("ERROR: sched: failed to grow atoms array\n");
-+ free(event);
-+ return NULL;
-+ }
-+ task->atoms = atoms_p;
- task->nr_events++;
-- size = sizeof(struct sched_atom *) * task->nr_events;
-- task->atoms = realloc(task->atoms, size);
-- BUG_ON(!task->atoms);
-
- task->atoms[idx] = event;
-
-@@ -401,6 +412,8 @@ static void add_sched_event_run(struct perf_sched *sched, struct task_desc *task
- }
-
- event = get_new_event(task, timestamp);
-+ if (event == NULL)
-+ return;
-
- event->type = SCHED_EVENT_RUN;
- event->duration = duration;
-@@ -414,6 +427,8 @@ static void add_sched_event_wakeup(struct perf_sched *sched, struct task_desc *t
- struct sched_atom *event, *wakee_event;
-
- event = get_new_event(task, timestamp);
-+ if (event == NULL)
-+ return;
- event->type = SCHED_EVENT_WAKEUP;
- event->wakee = wakee;
-
-@@ -428,6 +443,10 @@ static void add_sched_event_wakeup(struct perf_sched *sched, struct task_desc *t
- }
-
- wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem));
-+ if (!wakee_event->wait_sem) {
-+ pr_err("ERROR: sched: failed to allocate semaphore\n");
-+ return;
-+ }
- sem_init(wakee_event->wait_sem, 0, 0);
- wakee_event->specific_wait = 1;
- event->wait_sem = wakee_event->wait_sem;
-@@ -440,6 +459,9 @@ static void add_sched_event_sleep(struct perf_sched *sched, struct task_desc *ta
- {
- struct sched_atom *event = get_new_event(task, timestamp);
-
-+ if (event == NULL)
-+ return;
-+
- event->type = SCHED_EVENT_SLEEP;
-
- sched->nr_sleep_events++;
---
-2.53.0
-
+++ /dev/null
-From d2dcb677658e2fcaccfdd4bd01999598f59266d5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 1 Jun 2026 19:53:41 -0300
-Subject: perf sched: Replace BUG_ON on invalid CPU with graceful skip
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 1e2c83f732deb329ebce23e26cbc482f4c4bf194 ]
-
-latency_switch_event(), latency_runtime_event(), and map_switch_event()
-use BUG_ON(cpu >= MAX_CPUS || cpu < 0) to validate the sample CPU.
-When PERF_SAMPLE_CPU is absent from the sample type,
-evsel__parse_sample() initializes sample->cpu to (u32)-1. Casting
-this to int yields -1, which triggers the BUG_ON and aborts perf sched.
-
-The central CPU validation in perf_session__deliver_event() intentionally
-preserves the (u32)-1 sentinel for downstream tools like perf script
-and perf inject, so leaf callbacks must handle it themselves.
-
-Replace the three BUG_ON calls with graceful skips using pr_warning(),
-matching the existing pattern in process_sched_switch_event() and
-process_sched_runtime_event() earlier in the same file. Include the
-file offset for cross-referencing with perf report -D.
-
-Reported-by: sashiko-bot@kernel.org # Running on a local machine
-Reviewed-by: Ian Rogers <irogers@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Stable-dep-of: 8cbca8a480e1 ("perf sched: Fix NULL dereference in latency_runtime_event")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/builtin-sched.c | 22 +++++++++++++++++++---
- 1 file changed, 19 insertions(+), 3 deletions(-)
-
-diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
-index 6584e39b2a8d48..2c954de3ed419c 100644
---- a/tools/perf/builtin-sched.c
-+++ b/tools/perf/builtin-sched.c
-@@ -1154,7 +1154,12 @@ static int latency_switch_event(struct perf_sched *sched,
- int cpu = sample->cpu, err = -1;
- s64 delta;
-
-- BUG_ON(cpu >= MAX_CPUS || cpu < 0);
-+ /* perf.data is untrusted input — CPU may be absent or corrupted */
-+ if (cpu >= MAX_CPUS || cpu < 0) {
-+ pr_warning("WARNING: at offset %#" PRIx64 ": out-of-bound sample CPU %d, skipping sample\n",
-+ sample->file_offset, cpu);
-+ return 0;
-+ }
-
- timestamp0 = sched->cpu_last_switched[cpu];
- sched->cpu_last_switched[cpu] = timestamp;
-@@ -1225,7 +1230,13 @@ static int latency_runtime_event(struct perf_sched *sched,
- if (thread == NULL)
- return -1;
-
-- BUG_ON(cpu >= MAX_CPUS || cpu < 0);
-+ /* perf.data is untrusted input — CPU may be absent or corrupted */
-+ if (cpu >= MAX_CPUS || cpu < 0) {
-+ pr_warning("WARNING: at offset %#" PRIx64 ": out-of-bound sample CPU %d, skipping sample\n",
-+ sample->file_offset, cpu);
-+ err = 0;
-+ goto out_put;
-+ }
- if (!atoms) {
- if (thread_atoms_insert(sched, thread))
- goto out_put;
-@@ -1581,7 +1592,12 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
- const char *color = PERF_COLOR_NORMAL;
- char stimestamp[32];
-
-- BUG_ON(this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0);
-+ /* perf.data is untrusted input — CPU may be absent or corrupted */
-+ if (this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0) {
-+ pr_warning("WARNING: at offset %#" PRIx64 ": out-of-bound sample CPU %d, skipping sample\n",
-+ sample->file_offset, this_cpu.cpu);
-+ return 0;
-+ }
-
- if (this_cpu.cpu > sched->max_cpu.cpu)
- sched->max_cpu = this_cpu;
---
-2.53.0
-
+++ /dev/null
-From cacf618291ddfa81fd61d7dbbab226c40fb6e016 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 8 Jun 2026 08:12:34 -0300
-Subject: perf symbols: Add bounds checks to elf_read_build_id() note iteration
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit acc56d3941fc2997a5a21ea9233a8ac3d87c4f2f ]
-
-elf_read_build_id() iterates ELF notes using pointer arithmetic
-driven by n_namesz and n_descsz from the note headers. Neither
-the note header read nor the subsequent name/desc advances are
-checked against the section boundary. A malformed ELF file with
-oversized note sizes causes out-of-bounds reads past the section
-data buffer.
-
-Add two bounds checks: verify the note header fits within the
-remaining section data, and verify that namesz + descsz (after
-alignment) fits before advancing the pointer.
-
-Fixes: fd7a346ea292074e ("perf symbols: Filename__read_build_id should look at .notes section too")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-elf.c | 18 ++++++++++++++++--
- 1 file changed, 16 insertions(+), 2 deletions(-)
-
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 0db4959dbd22bd..0b8956740fd8ac 100644
---- a/tools/perf/util/symbol-elf.c
-+++ b/tools/perf/util/symbol-elf.c
-@@ -540,10 +540,24 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size)
- ptr = data->d_buf;
- while (ptr < (data->d_buf + data->d_size)) {
- GElf_Nhdr *nhdr = ptr;
-- size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
-- descsz = NOTE_ALIGN(nhdr->n_descsz);
-+ size_t namesz, descsz, remaining;
- const char *name;
-
-+ /* ensure the note header fits within the section */
-+ if (ptr + sizeof(*nhdr) > data->d_buf + data->d_size)
-+ break;
-+
-+ namesz = NOTE_ALIGN(nhdr->n_namesz);
-+ descsz = NOTE_ALIGN(nhdr->n_descsz);
-+
-+ /* validate individually to avoid size_t overflow on 32-bit */
-+ remaining = data->d_buf + data->d_size - ptr - sizeof(*nhdr);
-+ if (namesz > remaining || descsz > remaining - namesz) {
-+ pr_warning("%s: oversized note: n_namesz=%u, n_descsz=%u\n",
-+ __func__, nhdr->n_namesz, nhdr->n_descsz);
-+ break;
-+ }
-+
- ptr += sizeof(*nhdr);
- name = ptr;
- ptr += namesz;
---
-2.53.0
-
+++ /dev/null
-From 2e0ef827e17e152678f37f83b5adfc057684ff4b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 10 Jun 2026 16:09:45 -0300
-Subject: perf symbols: Add bounds checks to read_build_id() note iteration in
- minimal build
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 52e582e316c48c53bb3082c29f7862ebc554087e ]
-
-symbol-minimal.c's read_build_id() iterates ELF notes with the same
-pattern as symbol-elf.c's elf_read_build_id(): pointer arithmetic
-driven by n_namesz and n_descsz from 32-bit note header fields,
-without validating that the name and desc fit within the note section
-data. A malformed ELF file with oversized note sizes causes
-out-of-bounds reads past the section data buffer.
-
-Add the same bounds check as the libelf path: validate namesz and
-descsz individually against remaining data before advancing the
-pointer, avoiding size_t overflow on 32-bit.
-
-Fixes: b691f64360ecec49 ("perf symbols: Implement poor man's ELF parser")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-minimal.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
-index f9eb0bee7f157a..cd3bef5644a0b6 100644
---- a/tools/perf/util/symbol-minimal.c
-+++ b/tools/perf/util/symbol-minimal.c
-@@ -1,3 +1,4 @@
-+#include "debug.h"
- #include "dso.h"
- #include "symbol.h"
- #include "symsrc.h"
-@@ -45,7 +46,7 @@ static int read_build_id(void *note_data, size_t note_len, struct build_id *bid,
- ptr = note_data;
- while (ptr < (note_data + note_len)) {
- const char *name;
-- size_t namesz, descsz;
-+ size_t namesz, descsz, remaining;
-
- nhdr = ptr;
- if (need_swap) {
-@@ -57,6 +58,14 @@ static int read_build_id(void *note_data, size_t note_len, struct build_id *bid,
- namesz = NOTE_ALIGN(nhdr->n_namesz);
- descsz = NOTE_ALIGN(nhdr->n_descsz);
-
-+ /* validate individually to avoid size_t overflow on 32-bit */
-+ remaining = note_data + note_len - ptr - sizeof(*nhdr);
-+ if (namesz > remaining || descsz > remaining - namesz) {
-+ pr_warning("%s: oversized note: n_namesz=%u, n_descsz=%u\n",
-+ __func__, nhdr->n_namesz, nhdr->n_descsz);
-+ break;
-+ }
-+
- ptr += sizeof(*nhdr);
- name = ptr;
- ptr += namesz;
---
-2.53.0
-
+++ /dev/null
-From 4a35992f8699338722fde29faa2b6362dd3d3bee Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 21:05:15 -0300
-Subject: perf symbols: Bounds-check .gnu_debuglink section data
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 9c74f0aab398cb32ab250401f323c0fdc9a3a496 ]
-
-filename__read_debuglink() copies .gnu_debuglink section data into a
-caller-provided buffer via:
-
- strncpy(debuglink, data->d_buf, size);
-
-where size is PATH_MAX. If the ELF section is smaller than size and
-lacks a null terminator, strncpy reads past data->d_buf into adjacent
-memory. A malformed ELF file can trigger this, potentially causing a
-segfault or leaking heap data.
-
-Additionally, strncpy does not guarantee null termination when the
-source fills the buffer.
-
-Replace with an explicit memcpy bounded by both the output buffer
-size and the actual section data size (data->d_size), followed by
-explicit null termination.
-
-Fixes: e5a1845fc0aeca85 ("perf symbols: Split out util/symbol-elf.c")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-elf.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 4631895e4dae6a..5203902b417daa 100644
---- a/tools/perf/util/symbol-elf.c
-+++ b/tools/perf/util/symbol-elf.c
-@@ -791,7 +791,14 @@ int filename__read_debuglink(const char *filename, char *debuglink,
- goto out_elf_end;
-
- /* the start of this section is a zero-terminated string */
-- strncpy(debuglink, data->d_buf, size);
-+ if (data->d_size > 0) {
-+ size_t len = min(size - 1, data->d_size);
-+
-+ memcpy(debuglink, data->d_buf, len);
-+ debuglink[len] = '\0';
-+ } else {
-+ debuglink[0] = '\0';
-+ }
-
- err = 0;
-
---
-2.53.0
-
+++ /dev/null
-From d5053d50caeed0c053a768ffe3051250a6b3b0c8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 22:40:20 -0300
-Subject: perf symbols: Bounds-check descsz in sysfs__read_build_id() GNU
- fallback
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 1b4e9fbdeabc549965e70ac0cd8095d57ff6df06 ]
-
-When sysfs__read_build_id() matches NT_GNU_BUILD_ID with the right
-namesz but the name content is not "GNU", it falls back to reading
-descsz bytes into the stack buffer bf[BUFSIZ]:
-
- } else if (read(fd, bf, descsz) != (ssize_t)descsz)
-
-Unlike the else branch which validates namesz + descsz against
-sizeof(bf), this path passes descsz directly to read() without any
-bounds check. A crafted sysfs file with a large n_descsz overflows
-the 8192-byte stack buffer.
-
-Add a descsz > sizeof(bf) check before the read, breaking out of
-the loop on oversized values.
-
-Fixes: e5a1845fc0aeca85 ("perf symbols: Split out util/symbol-elf.c")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-elf.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 5203902b417daa..0db4959dbd22bd 100644
---- a/tools/perf/util/symbol-elf.c
-+++ b/tools/perf/util/symbol-elf.c
-@@ -691,8 +691,13 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
- err = 0;
- break;
- }
-- } else if (read(fd, bf, descsz) != (ssize_t)descsz)
-- break;
-+ } else {
-+ /* descsz from untrusted file — clamp to buffer */
-+ if (descsz > sizeof(bf))
-+ break;
-+ if (read(fd, bf, descsz) != (ssize_t)descsz)
-+ break;
-+ }
- } else {
- size_t n;
-
---
-2.53.0
-
+++ /dev/null
-From cb6b7932993ca3fab719ad5073b838ca34f5626b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 10 Jun 2026 19:32:22 -0300
-Subject: perf symbols: Break infinite loop on zero-filled notes in
- sysfs__read_build_id()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 063c647b24f640657d6d9e2e90d620ea3ee19ae6 ]
-
-sysfs__read_build_id() iterates ELF note headers from sysfs files in a
-while(1) loop. If the file contains a zero-filled note header (both
-n_namesz and n_descsz are 0), the code computes n = namesz + descsz = 0
-and calls read(fd, bf, 0). read() with count 0 returns 0, which
-matches the expected (ssize_t)n value, so the error check passes and
-the loop repeats — reading the same zero bytes and spinning forever.
-
-This can happen with corrupted or zero-padded sysfs pseudo-files.
-
-Add a check for n == 0 before the read, since no valid ELF note has
-both name and description of zero length.
-
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Fixes: f1617b40596cb341 ("perf symbols: Record the build_ids of kernel modules too")
-Reviewed-by: Ian Rogers <irogers@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-elf.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 0b8956740fd8ac..7e1b62388f0b72 100644
---- a/tools/perf/util/symbol-elf.c
-+++ b/tools/perf/util/symbol-elf.c
-@@ -723,6 +723,9 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
- } else {
- n = namesz + descsz;
- }
-+ /* no valid note has both namesz and descsz zero */
-+ if (n == 0)
-+ break;
- if (read(fd, bf, n) != (ssize_t)n)
- break;
- }
---
-2.53.0
-
+++ /dev/null
-From b3aabfd0e9b899f01606b5068815b1d4a4f542ab Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 21:04:50 -0300
-Subject: perf symbols: Fix signed overflow in sysfs__read_build_id() size
- check
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 6eaa8ee3e2abe5112e80e94c27196bb175689469 ]
-
-sysfs__read_build_id() reads ELF note headers from sysfs files. The
-note's namesz and descsz fields are used to compute the skip size:
-
- int n = namesz + descsz;
- if (n > (int)sizeof(bf))
-
-Both namesz and descsz are size_t from NOTE_ALIGN() of 32-bit note
-header fields. Their sum can exceed INT_MAX, overflowing the signed
-int n to a negative value. The check n > sizeof(bf) then evaluates
-false (negative < positive in signed comparison), and read(fd, bf, n)
-reinterprets the negative n as a huge size_t count — the kernel writes
-up to MAX_RW_COUNT bytes into the 8192-byte stack buffer.
-
-In practice the overflow is bounded by the sysfs file's actual size,
-so a real sysfs notes file won't trigger it organically. But crafted
-input (e.g. via a mounted debugfs/sysfs image) could.
-
-Fix by validating namesz and descsz individually against the buffer
-size before summing, and change n to size_t to avoid the signed
-overflow entirely.
-
-Fixes: f1617b40596cb341 ("perf symbols: Record the build_ids of kernel modules too")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/symbol-elf.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
-index 29c9348c30f00c..4631895e4dae6a 100644
---- a/tools/perf/util/symbol-elf.c
-+++ b/tools/perf/util/symbol-elf.c
-@@ -694,14 +694,17 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
- } else if (read(fd, bf, descsz) != (ssize_t)descsz)
- break;
- } else {
-- int n = namesz + descsz;
-+ size_t n;
-
-- if (n > (int)sizeof(bf)) {
-+ /* int sum of namesz+descsz can overflow negative, bypassing size check */
-+ if (namesz > sizeof(bf) || descsz > sizeof(bf) - namesz) {
- n = sizeof(bf);
- pr_debug("%s: truncating reading of build id in sysfs file %s: n_namesz=%u, n_descsz=%u.\n",
- __func__, filename, nhdr.n_namesz, nhdr.n_descsz);
-+ } else {
-+ n = namesz + descsz;
- }
-- if (read(fd, bf, n) != n)
-+ if (read(fd, bf, n) != (ssize_t)n)
- break;
- }
- }
---
-2.53.0
-
+++ /dev/null
-From 9301ca807e2375bfae0522c7d7584b9d9778ac75 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 4 Jun 2026 18:14:23 -0300
-Subject: perf tools: Add bounds check to cpu__get_node()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 1e7921d7227de5da0dfc167943092c823ec7e49b ]
-
-cpu__get_node() accesses cpunode_map[cpu.cpu] without checking against
-max_cpu_num, the allocation size of cpunode_map. Callers such as
-builtin-kmem.c:evsel__process_alloc_event() pass sample->cpu from
-perf.data events, which may exceed the host's CPU count when analyzing
-cross-machine recordings.
-
-Add a bounds check against max_cpu_num before indexing, returning -1
-for out-of-range values. This is a central fix that protects all
-callers.
-
-Fixes: 86895b480a2f ("perf stat: Add --per-node agregation support")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/cpumap.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
-index 8486ca3bec75ff..370bc498b7a2e4 100644
---- a/tools/perf/util/cpumap.c
-+++ b/tools/perf/util/cpumap.c
-@@ -486,6 +486,10 @@ int cpu__get_node(struct perf_cpu cpu)
- return -1;
- }
-
-+ /* cpunode_map allocated for max_cpu_num entries; input may be untrusted */
-+ if (cpu.cpu < 0 || cpu.cpu >= max_cpu_num.cpu)
-+ return -1;
-+
- return cpunode_map[cpu.cpu];
- }
-
---
-2.53.0
-
+++ /dev/null
-From 1704db150b5cf93df32f3dabccc9f6f8142af308 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 6 Jun 2026 20:37:52 -0300
-Subject: perf tools: Fix get_max_num() size_t underflow on empty sysfs file
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 0a012113bb3a44482c163f16f4db03ccaa37a339 ]
-
-get_max_num() reads a sysfs file (cpu/possible, cpu/present, or
-node/possible) and scans backward from the end to find the last
-number. If the file is empty, filename__read_str() returns num == 0.
-The loop `while (--num)` decrements the size_t from 0 to SIZE_MAX,
-reading backward across the heap until a comma or hyphen is found
-or unmapped memory is hit.
-
-Add an early return for empty files before the backward scan.
-
-Fixes: 7780c25bae59fd04 ("perf tools: Allow ability to map cpus to nodes easily")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Reviewed-by: Ian Rogers <irogers@google.com>
-Cc: Don Zickus <dzickus@redhat.com>
-Cc: Ian Rogers <irogers@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/cpumap.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
-index 370bc498b7a2e4..4a882d4e183f26 100644
---- a/tools/perf/util/cpumap.c
-+++ b/tools/perf/util/cpumap.c
-@@ -366,6 +366,12 @@ static int get_max_num(char *path, int *max)
-
- buf[num] = '\0';
-
-+ /* empty file — nothing to parse */
-+ if (num == 0) {
-+ err = -1;
-+ goto out;
-+ }
-+
- /* start on the right, to find highest node num */
- while (--num) {
- if ((buf[num] == ',') || (buf[num] == '-')) {
---
-2.53.0
-
+++ /dev/null
-From c3ee7065b50220b910de1dcdc6ef7f557c458e44 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 7 Jun 2026 22:37:55 -0300
-Subject: perf tools: Fix thread__set_comm_from_proc() on empty comm file
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 31d596054550f793508abe7dd593853ece47d428 ]
-
-thread__set_comm_from_proc() calls procfs__read_str() then strips
-the trailing newline via comm[sz - 1] = '\0'. procfs__read_str()
-allocates the buffer before reading, so on an empty /proc/pid/comm
-(reachable during late exit teardown) it returns success with sz = 0
-and an unterminated heap buffer.
-
-The sz - 1 underflow was the original sashiko finding: it writes a
-null byte before the allocation. But even with a sz > 0 guard on
-the newline strip, the unterminated buffer would still be passed to
-thread__set_comm() which calls strlen() — an unbounded heap read.
-
-Fix by treating sz == 0 as failure: free the buffer and return -1.
-This is consistent with pmu.c's perf_pmu__parse_scale/unit which
-already treat len == 0 from filename__read_str as an error.
-
-Fixes: 2f3027ac28bf6bc3 ("perf thread: Introduce method to set comm from /proc/pid/self")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/thread.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
-index e3e5427e1c3c87..4098a677360e1f 100644
---- a/tools/perf/util/thread.c
-+++ b/tools/perf/util/thread.c
-@@ -283,6 +283,11 @@ int thread__set_comm_from_proc(struct thread *thread)
- if (!(snprintf(path, sizeof(path), "%d/task/%d/comm",
- thread->pid_, thread->tid) >= (int)sizeof(path)) &&
- procfs__read_str(path, &comm, &sz) == 0) {
-+ /* sz==0: read got nothing, e.g. race during exit teardown */
-+ if (sz == 0) {
-+ free(comm);
-+ return -1;
-+ }
- comm[sz - 1] = '\0';
- err = thread__set_comm(thread, comm, 0);
- }
---
-2.53.0
-
+++ /dev/null
-From b5b8bf8df53cfeec0fe46f74ab2311cd9ef939b4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 6 Jun 2026 20:57:49 -0300
-Subject: perf tools: Use perf_env__get_cpu_topology() in machine__resolve()
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 5484b43a0ec8231c36fba6ead654cb72dbba8b8f ]
-
-machine__resolve() accesses env->cpu[al->cpu].socket_id after checking
-al->cpu >= 0 and env->cpu != NULL, but without validating al->cpu
-against env->nr_cpus_avail. Since al->cpu comes from the untrusted
-perf.data sample, a crafted file with a large CPU index causes an
-out-of-bounds heap read.
-
-Use perf_env__get_cpu_topology() which validates both NULL and bounds.
-Also bounds-check al->cpu before the cast to struct perf_cpu (int16_t):
-without this, values like 65536 silently truncate to 0, bypassing the
-accessor's internal check and returning CPU 0's topology.
-
-Fixes: 0c4c4debb0adda4c ("perf tools: Add processor socket info to hist_entry and addr_location")
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Reviewed-by: Ian Rogers <irogers@google.com>
-Cc: Kan Liang <kan.liang@intel.com>
-Cc: Ian Rogers <irogers@google.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/event.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
-
-diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
-index 1fa14598b91669..d4d2c2141b8554 100644
---- a/tools/perf/util/event.c
-+++ b/tools/perf/util/event.c
-@@ -12,6 +12,7 @@
- #include <linux/zalloc.h>
- #include "cpumap.h"
- #include "dso.h"
-+#include "env.h"
- #include "event.h"
- #include "debug.h"
- #include "hist.h"
-@@ -710,8 +711,18 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
- if (al->cpu >= 0) {
- struct perf_env *env = machine->env;
-
-- if (env && env->cpu)
-- al->socket = env->cpu[al->cpu].socket_id;
-+ /*
-+ * Bounds-check al->cpu (s32) before casting to struct perf_cpu
-+ * (int16_t): without this, e.g. 65536 truncates to 0 and silently
-+ * returns CPU 0's topology. Can go once perf_cpu.cpu is widened.
-+ */
-+ if (env && al->cpu < env->nr_cpus_avail) {
-+ struct cpu_topology_map *topo;
-+
-+ topo = perf_env__get_cpu_topology(env, (struct perf_cpu){ al->cpu });
-+ if (topo)
-+ al->socket = topo->socket_id;
-+ }
- }
-
- if (al->map) {
---
-2.53.0
-
+++ /dev/null
-From a4e123a7685ae48e69ae8aac9f1df34f3d6e3daf Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 10 Jun 2026 20:34:38 -0300
-Subject: perf tools: Use snprintf() for root_dir path construction
-
-From: Arnaldo Carvalho de Melo <acme@redhat.com>
-
-[ Upstream commit 7b0df6f4d498b1608afccfd6dffb264e6da91693 ]
-
-get_kernel_version() in machine.c and dso__load_guest_kernel_sym() in
-symbol.c use sprintf() to construct paths by prepending root_dir to
-"/proc/version" and "/proc/kallsyms" respectively. Both write into
-PATH_MAX stack buffers, but root_dir comes from --guestmount or KVM
-configuration and is not length-checked. A root_dir at or near
-PATH_MAX causes a stack buffer overflow.
-
-Switch to snprintf() with sizeof(path) to prevent overflow.
-
-Reported-by: sashiko-bot <sashiko-bot@kernel.org>
-Fixes: a1645ce12adb6c9c ("perf: 'perf kvm' tool for monitoring guest performance from host")
-Cc: Zhang Yanmin <yanmin_zhang@linux.intel.com>
-Assisted-by: Claude:claude-opus-4.6
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/machine.c | 2 +-
- tools/perf/util/symbol.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
-index 9cd52f50ea7acf..419147da8d672b 100644
---- a/tools/perf/util/machine.c
-+++ b/tools/perf/util/machine.c
-@@ -1443,7 +1443,7 @@ static char *get_kernel_version(const char *root_dir)
- char *name, *tmp;
- const char *prefix = "Linux version ";
-
-- sprintf(version, "%s/proc/version", root_dir);
-+ snprintf(version, sizeof(version), "%s/proc/version", root_dir);
- file = fopen(version, "r");
- if (!file)
- return NULL;
-diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
-index b434f2398df5ac..bc79eace253591 100644
---- a/tools/perf/util/symbol.c
-+++ b/tools/perf/util/symbol.c
-@@ -2336,7 +2336,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map)
- if (!kallsyms_filename)
- return -1;
- } else {
-- sprintf(path, "%s/proc/kallsyms", machine->root_dir);
-+ snprintf(path, sizeof(path), "%s/proc/kallsyms", machine->root_dir);
- kallsyms_filename = path;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 7ee7f48413c42b90230de4a8e40898b757bc8e82 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <florian.fainelli@broadcom.com>
-Date: Wed, 13 May 2026 12:23:46 -0700
-Subject: perf trace beauty fcntl: Fix build with older kernel headers
-
-From: Florian Fainelli <florian.fainelli@broadcom.com>
-
-commit 7ee7f48413c42b90230de4a8e40898b757bc8e82 upstream.
-
-Toolchains with older kernel headers that do not include upstream commit
-c75b1d9421f80f41 ("fs: add fcntl() interface for setting/getting write
-life time hints") will now fail to build perf due to missing definitions
-for F_GET_RW_HINT/F_SET_RW_HINT/F_GET_FILE_RW_HINT/F_SET_FILE_RW_HINT.
-
-Provide a fallback definition for these when they are not already
-defined.
-
-Fixes: 9c47f66748381ecb ("perf trace beauty fcntl: Basic 'arg' beautifier")
-Reviewed-by: Ian Rogers <irogers@google.com>
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: James Clark <james.clark@linaro.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Markus Mayer <mmayer@broadcom.com>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- tools/perf/trace/beauty/fcntl.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/tools/perf/trace/beauty/fcntl.c
-+++ b/tools/perf/trace/beauty/fcntl.c
-@@ -9,6 +9,22 @@
- #include <linux/kernel.h>
- #include <uapi/linux/fcntl.h>
-
-+#ifndef F_GET_RW_HINT
-+#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11)
-+#endif
-+
-+#ifndef F_SET_RW_HINT
-+#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12)
-+#endif
-+
-+#ifndef F_GET_FILE_RW_HINT
-+#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
-+#endif
-+
-+#ifndef F_SET_FILE_RW_HINT
-+#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14)
-+#endif
-+
- static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size, bool show_prefix)
- {
- return val ? scnprintf(bf, size, "%s", "0") :
+++ /dev/null
-From 47915e855fb38b42133e31ba917d99565f862154 Mon Sep 17 00:00:00 2001
-From: Sandipan Das <sandipan.das@amd.com>
-Date: Fri, 10 Jul 2026 22:04:49 +0530
-Subject: perf/x86/amd/brs: Fix kernel address leakage
-
-From: Sandipan Das <sandipan.das@amd.com>
-
-commit 47915e855fb38b42133e31ba917d99565f862154 upstream.
-
-A user-only branch stack can contain branches that originate from
-the kernel. As a result, kernel addresses are exposed to user space
-even when PERF_SAMPLE_BRANCH_USER is requested. On AMD processors
-supporting X86_FEATURE_BRS (Zen 3 only), perf can still report entries
-such as SYSRET/interrupt returns for which the branch-from addresses
-are in the kernel.
-
-E.g.
-
- $ perf record -j any,u -c 4000 -e branch-brs -o - -- \
- perf bench syscall basic --loop 1000 | \
- perf script -i - -F brstack|tr ' ' '\n'| \
- grep -E '0x[89a-f][0-9a-f]{15}'
-
- ...
- 0xffffffff810001c4/0x72e2e32955eb/-/-/-/0//-
- 0xffffffff810001c4/0x72e2d94a9821/-/-/-/0//-
- 0xffffffff810001c4/0x72e2d94ffa1b/-/-/-/0//-
- ...
-
-BRS provides no hardware branch filtering, so privilege level
-filtering is performed entirely in software. However, amd_brs_match_plm()
-only validates the branch-to address against the requested privilege
-levels. For branches from the kernel to user space, the branch-from
-address is left unchecked and is leaked. Extend the software filter to
-also validate the branch-from address, so that any branch record whose
-branch-from address is in the kernel is dropped when
-PERF_SAMPLE_BRANCH_USER is requested.
-
-Fixes: 8910075d61a3 ("perf/x86/amd: Enable branch sampling priv level filtering")
-Reported-by: Sashiko <sashiko-bot@kernel.org>
-Signed-off-by: Sandipan Das <sandipan.das@amd.com>
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Cc: stable@vger.kernel.org
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Stephane Eranian <eranian@google.com>
-Link: https://patch.msgid.link/f05931c4f89a146c364bd5dc6b8170b1ac611c65.1783701239.git.sandipan.das@amd.com
-Closes: https://lore.kernel.org/all/20260710110235.F3FD81F000E9@smtp.kernel.org/
-[sandipan: backport to linux-6.1.y]
-Signed-off-by: Sandipan Das <sandipan.das@amd.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/events/amd/brs.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/x86/events/amd/brs.c
-+++ b/arch/x86/events/amd/brs.c
-@@ -262,13 +262,13 @@ void amd_brs_disable_all(void)
- amd_brs_disable();
- }
-
--static bool amd_brs_match_plm(struct perf_event *event, u64 to)
-+static bool amd_brs_match_plm(struct perf_event *event, u64 from, u64 to)
- {
- int type = event->attr.branch_sample_type;
- int plm_k = PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV;
- int plm_u = PERF_SAMPLE_BRANCH_USER;
-
-- if (!(type & plm_k) && kernel_ip(to))
-+ if (!(type & plm_k) && (kernel_ip(to) || kernel_ip(from)))
- return 0;
-
- if (!(type & plm_u) && !kernel_ip(to))
-@@ -341,11 +341,11 @@ void amd_brs_drain(void)
- */
- to = (u64)(((s64)to << shift) >> shift);
-
-- if (!amd_brs_match_plm(event, to))
-- continue;
--
- rdmsrl(brs_from(brs_idx), from);
-
-+ if (!amd_brs_match_plm(event, from, to))
-+ continue;
-+
- perf_clear_branch_entry_bitfields(br+nr);
-
- br[nr].from = from;
-From 1d6c15b42b24fb241981e572e236b1c40414ef77 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
+From 73a4c02f94a98d94480c3e5c81450215a4da05ba Mon Sep 17 00:00:00 2001
+From: Sandipan Das <sandipan.das@amd.com>
Date: Mon, 1 Jun 2026 20:28:46 +0530
Subject: perf/x86/amd/core: Always use the NMI latency mitigation
From: Sandipan Das <sandipan.das@amd.com>
-[ Upstream commit 73a4c02f94a98d94480c3e5c81450215a4da05ba ]
+commit 73a4c02f94a98d94480c3e5c81450215a4da05ba upstream.
Commit df4d29732fda ("perf/x86/amd: Change/fix NMI latency mitigation
to use a timestamp") fixed handling of late-arriving NMIs but limited
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/29a3c970da289ab8f24282933bdb36545c0403e8.1780325517.git.sandipan.das@amd.com
-Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- arch/x86/events/amd/core.c | 6 +++---
+ arch/x86/events/amd/core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
-diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
-index 5a6ef45dc9b68b..d1f882cf418d4f 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
-@@ -1352,12 +1352,12 @@ static int __init amd_core_pmu_init(void)
+@@ -1352,12 +1352,12 @@ static int __init amd_core_pmu_init(void
u64 even_ctr_mask = 0ULL;
int i;
/*
* If core performance counter extensions exists, we must use
* MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
---
-2.53.0
-
+++ /dev/null
-From 2a892294b83f541115c94b0bb637f39bef187657 Mon Sep 17 00:00:00 2001
-From: Sandipan Das <sandipan.das@amd.com>
-Date: Fri, 10 Jul 2026 16:15:27 +0530
-Subject: perf/x86/amd/lbr: Fix kernel address leakage
-
-From: Sandipan Das <sandipan.das@amd.com>
-
-commit 2a892294b83f541115c94b0bb637f39bef187657 upstream.
-
-A user-only branch stack can contain branches that originate from
-the kernel. As a result, kernel addresses are exposed to user space
-even when PERF_SAMPLE_BRANCH_USER is requested. On AMD processors
-supporting X86_FEATURE_AMD_LBR_V2, perf can still report SYSRET/ERET
-entries for which the branch-from addresses are in the kernel.
-
-E.g.
-
- $ perf record -e cycles -o - -j any,save_type,u -- \
- perf bench syscall basic --loop 1000 | \
- perf script -i - -F brstack|tr ' ' '\n'| \
- grep -E '0x[89a-f][0-9a-f]{15}'
-
- ...
- 0xffffffff81001268/0x717a90a38f1a/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a90a39157/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a90a2c628/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a90a41b60/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a90a260db/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a90a260db/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a8bef1c30/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- 0xffffffff81001268/0x717a8e4d3c90/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
- ...
-
-The reason is that the hardware filter only considers the privilege
-level applicable to the branch target. Extend software filtering to
-also validate the branch-from addresses against br_sel, so that any
-branch record whose branch-from address is in the kernel is dropped
-when PERF_SAMPLE_BRANCH_USER is requested.
-
-Fixes: f4f925dae741 ("perf/x86/amd/lbr: Add LbrExtV2 hardware branch filter support")
-Reported-by: Ian Rogers <irogers@google.com>
-Signed-off-by: Sandipan Das <sandipan.das@amd.com>
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Cc: stable@vger.kernel.org
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: https://patch.msgid.link/a898a29725f6b2f30518354cdc2e432db66c43cf.1783680119.git.sandipan.das@amd.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/events/amd/lbr.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/arch/x86/events/amd/lbr.c
-+++ b/arch/x86/events/amd/lbr.c
-@@ -124,7 +124,8 @@ static void amd_pmu_lbr_filter(void)
- }
-
- /* If type does not correspond, then discard */
-- if (type == X86_BR_NONE || (br_sel & type) != type) {
-+ if (type == X86_BR_NONE || (br_sel & type) != type ||
-+ (!(br_sel & X86_BR_KERNEL) && kernel_ip(cpuc->lbr_entries[i].from))) {
- cpuc->lbr_entries[i].from = 0; /* mark invalid */
- compress = true;
- }
+++ /dev/null
-From stable+bounces-276818-greg=kroah.com@vger.kernel.org Thu Jul 16 21:03:47 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 16 Jul 2026 15:03:40 -0400
-Subject: perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()
-To: stable@vger.kernel.org
-Cc: Zide Chen <zide.chen@intel.com>, "Peter Zijlstra (Intel)" <peterz@infradead.org>, Dapeng Mi <dapeng1.mi@linux.intel.com>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260716190340.1045396-1-sashal@kernel.org>
-
-From: Zide Chen <zide.chen@intel.com>
-
-[ Upstream commit 9a0bb848a37150aeccc10088e141339917d995dc ]
-
-On some Raptor Cove CPUs, enabling uncore PMON globally at driver init
-may increase power consumption even when no perf events are in use.
-
-Drop adl_uncore_msr_init_box() and defer programming the global control
-register to enable_box(), so it is only set when a box is actually used.
-
-IMC and IMC freerunning counters use a separate control path and are
-unaffected.
-
-Fixes: 772ed05f3c5c ("perf/x86/intel/uncore: Add Alder Lake support")
-Signed-off-by: Zide Chen <zide.chen@intel.com>
-Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
-Cc: stable@vger.kernel.org
-Link: https://patch.msgid.link/20260602144908.263680-5-zide.chen@intel.com
-[ deleted adl_uncore_msr_init_box() in its 6.12 wrmsrl() spelling since the tree predates the wrmsrq() rename ]
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/events/intel/uncore_snb.c | 7 -------
- 1 file changed, 7 deletions(-)
-
---- a/arch/x86/events/intel/uncore_snb.c
-+++ b/arch/x86/events/intel/uncore_snb.c
-@@ -537,12 +537,6 @@ void tgl_uncore_cpu_init(void)
- skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
- }
-
--static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
--{
-- if (box->pmu->pmu_idx == 0)
-- wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
--}
--
- static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
- {
- wrmsrl(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
-@@ -561,7 +555,6 @@ static void adl_uncore_msr_exit_box(stru
- }
-
- static struct intel_uncore_ops adl_uncore_msr_ops = {
-- .init_box = adl_uncore_msr_init_box,
- .enable_box = adl_uncore_msr_enable_box,
- .disable_box = adl_uncore_msr_disable_box,
- .exit_box = adl_uncore_msr_exit_box,
nfsd-change-nfs4_client_to_reclaim-to-allocate-data.patch
mm-vmscan-flush-deferred-tlb-before-freeing-large-fo.patch
bluetooth-iso-copy-base-if-service-data-matches-eir_.patch
-perf-trace-beauty-fcntl-fix-build-with-older-kernel-headers.patch
eventpoll-don-t-decrement-ep-refcount-while-still-holding-the-ep-mutex.patch
file-add-fput-cleanup-helper.patch
eventpoll-use-hlist_is_singular_node-in-__ep_remove.patch
eventpoll-fix-ep_remove-struct-eventpoll-struct-file-uaf.patch
acpi-cppc-suppress-ubsan-warning-caused-by-field-misuse.patch
rust-kbuild-set-frame-pointer-llvm-module-flag-for-config_frame_pointer.patch
-perf-core-detach-event-groups-during-remove_on_exec.patch
virtio_net-support-dynamic-rss-indirection-table-siz.patch
mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
usb-gadget-function-rndis-add-length-check-to-response-query.patch
lib-test_meminit-use-for-bools.patch
configfs_lookup-don-t-leave-s_dentry-dangling-on-fai.patch
bpftool-use-libbpf-error-code-for-flow-dissector-que.patch
-perf-x86-amd-core-always-use-the-nmi-latency-mitigat.patch
ocfs2-rebase-copied-fsdlm-lvb-pointers-in-locking_st.patch
ocfs2-fix-buffer-head-management-in-ocfs2_read_block.patch
ocfs2-reject-fitrim-ranges-shorter-than-a-cluster.patch
pci-check-rom-header-and-data-structure-addr-before-.patch
x86-platform-olpc-xo15-drop-wakeup-source-on-driver-.patch
platform-x86-xo15-ebook-fix-wakeup-source-and-gpe-ha.patch
-perf-sched-add-missing-mmap2-handler-in-timehist.patch
pci-loongson-do-not-ignore-downstream-devices-on-ext.patch
bus-mhi-ep-fix-potential-deadlock-in-mhi_ep_reset_wo.patch
phy-phy-can-transceiver-check-driver-match-and-drive.patch
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch
-perf-header-sanity-check-header_event_desc-attr.size.patch
iio-light-si1133-reset-counter-to-prevent-race-condi.patch
iio-light-si1133-prevent-race-condition-on-timeout.patch
iio-magnetometer-ak8975-fix-potential-kernel-stack-m.patch
fs-ntfs3-add-bounds-check-to-run_get_highest_vcn.patch
drm-amd-display-add-missing-kdoc-for-allm-parameters.patch
dmaengine-imx-sdma-refine-spba-bus-searching-in-prob.patch
-perf-fix-off-by-one-stack-buffer-overflow-in-kallsym.patch
-perf-sched-replace-bug_on-on-invalid-cpu-with-gracef.patch
-perf-sched-fix-null-dereference-in-latency_runtime_e.patch
-perf-tools-add-bounds-check-to-cpu__get_node.patch
-perf-mmap-guard-cpu__get_node-return-in-aio_bind.patch
-perf-sched-clean-up-idle_threads-entry-on-init-failu.patch
-perf-sched-replace-bug_on-and-add-null-checks-in-rep.patch
-perf-mmap-fix-null-deref-in-aio-cleanup-on-alloc-fai.patch
-perf-c2c-fix-use-after-free-in-he__get_c2c_hists-err.patch
dmaengine-qcom-gpi-set-dma_private-capability.patch
dmaengine-fix-possible-use-after-free.patch
clk-qcom-a53-corrected-frequency-multiplier-for-1152.patch
nfsv4-flexfiles-honor-ff_flags_no_io_thru_mds-on-fat.patch
nfsv4-flexfiles-honor-ff_flags_no_io_thru_mds-in-pg_.patch
pci-mediatek-fix-operator-precedence-in-pcie_fts_num.patch
-perf-tools-fix-get_max_num-size_t-underflow-on-empty.patch
-perf-tools-use-perf_env__get_cpu_topology-in-machine.patch
pci-rcar-host-remove-unused-list_head-res.patch
-perf-sched-fix-idle-hist-callchain-display-using-wro.patch
-perf-bpf-use-scnprintf-in-snprintf_hex-and-synthesiz.patch
-perf-hists-fix-snprintf-in-hists__scnprintf_title-ui.patch
xprtrdma-check-frwr_wp_create-during-connect.patch
xprtrdma-document-and-assert-reply-handler-invariant.patch
xprtrdma-resize-reply-buffers-before-reposting-recei.patch
xprtrdma-sanitize-the-reply-credit-grant-after-parsi.patch
xprtrdma-repost-receive-buffers-for-malformed-replie.patch
xprtrdma-return-sendctx-slot-after-send-preparation-.patch
-perf-pmu-fix-pmu_id-heap-underwrite-on-empty-identif.patch
-perf-pmu-fix-perf_pmu__parse_scale-unit-oob-access-o.patch
tools-lib-api-fix-missing-null-termination-in-filena.patch
-perf-symbols-fix-signed-overflow-in-sysfs__read_buil.patch
-perf-symbols-bounds-check-.gnu_debuglink-section-dat.patch
-perf-intel-pt-fix-snprintf-size-tracking-bug-in-insn.patch
-perf-tools-fix-thread__set_comm_from_proc-on-empty-c.patch
-perf-symbols-bounds-check-descsz-in-sysfs__read_buil.patch
tools-lib-api-fix-filename__write_int-writing-uninit.patch
tools-lib-api-fix-mount_overload-snprintf-truncation.patch
-perf-bpf-add-null-check-for-btf__type_by_id-in-synth.patch
-perf-symbols-add-bounds-checks-to-elf_read_build_id-.patch
-perf-symbols-add-bounds-checks-to-read_build_id-note.patch
pci-mediatek-fix-possible-truncation-in-mtk_pcie_par.patch
pci-mediatek-use-actual-physical-address-instead-of-.patch
revert-pci-msi-unmap-msi-x-region-on-error.patch
i3c-master-prevent-reuse-of-dynamic-address-on-devic.patch
apparmor-fix-label-can-not-be-immediately-before-a-d.patch
sparc-led-avoid-trimming-a-newline-from-empty-writes.patch
-perf-symbols-break-infinite-loop-on-zero-filled-note.patch
-perf-tools-use-snprintf-for-root_dir-path-constructi.patch
-perf-bpf-validate-func_info_rec_size-and-sub_id-in-s.patch
-perf-bpf-bounds-check-array-offsets-in-bpil_offs_to_.patch
spi-dw-fix-wrong-baudr-setting-after-resume.patch
xfrm-add-new-packet-offload-flag.patch
xfrm-use-the-xfrm_gro-to-indicate-a-gro-call-on-inpu.patch
xfrm-support-crypto-offload-for-inbound-ipv6-esp-pac.patch
xfrm-annotate-data-races-around-xfrm_policy_count-an.patch
xfrm-validate-selector-family-and-prefixlen-during-m.patch
-perf-machine-use-snprintf-for-guestmount-path-constr.patch
asoc-tlv320aic3x-restrict-clkdiv-bypass-q-values-in-.patch
drm-amdkfd-avoid-double-unpin-of-doorbell-mmio-bos-o.patch
drm-amdkfd-fix-list_del-corruption-in-kfd_criu_resum.patch
tools-power-x86-intel-speed-select-harden-daemon-pidfile-open.patch
x86-boot-validate-console-uart8250-baud-rate-to-fix-early-boot-hang.patch
x86-boot-reject-too-long-acpi_rsdp-values.patch
-perf-x86-amd-lbr-fix-kernel-address-leakage.patch
batman-adv-gw-acquire-ethernet-header-only-after-skb-realloc.patch
batman-adv-access-unicast_ttvn-skb-data-only-after-skb-realloc.patch
batman-adv-dat-acquire-arp-hw-source-only-after-skb-realloc.patch
mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch
mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch
mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch
-perf-x86-amd-brs-fix-kernel-address-leakage.patch
acpi-nfit-core-fix-acpi_nfit_init-error-cleanup.patch
iio-imu-adis-add-irqf_no_thread-to-non-fifo-trigger-irq.patch
iio-hid-sensor-rotation-fix-stale-or-zero-output-when-reading-raw-values.patch
ksmbd-track-the-connection-owning-a-byte-range-lock.patch
writeback-avoid-contention-on-wb-list_lock-when-switching-inodes.patch
writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch
-perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch
proc-use-generic-setattr-for-proc-pid-net.patch
proc-move-fdinfo-ptrace_mode_read-check-into-the-inode-.permission-operation.patch
proc-rename-proc_setattr-to-proc_nochmod_setattr.patch
alsa-seq-check-ump-support-for-midi_version-change.patch
iio-imu-inv_icm42600-fix-timestamp-clock-period-by-using-lower-value.patch
alsa-seq-fix-uninitialised-heap-leak-in-snd_seq_event_dup.patch
+perf-x86-amd-core-always-use-the-nmi-latency-mitigation.patch