From 60f2f5b7650bb8779af3087ef429fad4ed74a5c8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 2 Aug 2026 11:27:10 -0300 Subject: [PATCH] perf header: Use write lock when translating BPF prog info pointers write_bpf_prog_info() holds a read lock while temporarily mutating info_linear via bpil_addr_to_offs()/bpil_offs_to_addr(). Between these two calls, the pointers in info_linear contain file offsets instead of heap addresses. Concurrent readers holding the same read lock see the file offsets and dereference them as pointers. Use down_write()/up_write() instead of down_read()/up_read() to exclude concurrent readers during the addr-to-offset-to-addr translation window. Fixes: 63ac7968a1fb ("perf bpf: Save bpf_prog_info information as headers to perf.data") Reported-by: sashiko-bot Cc: Song Liu Reviewed-by: Ian Rogers Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Namhyung Kim --- tools/perf/util/header.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e90e541f546b..7db7da090a1e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1120,7 +1120,8 @@ static int write_bpf_prog_info(struct feat_fd *ff __maybe_unused, struct rb_node *next; int ret = 0; - down_read(&env->bpf_progs.lock); + /* write lock: bpil_addr_to_offs() temporarily mutates info_linear */ + down_write(&env->bpf_progs.lock); ret = do_write(ff, &env->bpf_progs.infos_cnt, sizeof(env->bpf_progs.infos_cnt)); @@ -1150,7 +1151,7 @@ static int write_bpf_prog_info(struct feat_fd *ff __maybe_unused, goto out; } out: - up_read(&env->bpf_progs.lock); + up_write(&env->bpf_progs.lock); return ret; #else pr_err("ERROR: Trying to write bpf_prog_info without libbpf support.\n");