perf tools: Fix build-id event recording
authorNamhyung Kim <namhyung@kernel.org>
Wed, 27 Nov 2024 03:13:31 +0000 (19:13 -0800)
committerNamhyung Kim <namhyung@kernel.org>
Mon, 2 Dec 2024 20:36:20 +0000 (12:36 -0800)
The build-id events written at the end of the record session are broken
due to unexpected data.  The write_buildid() writes the fixed length
event first and then variable length filename.

But a recent change made it write more data in the padding area
accidentally.  So readers of the event see zero-filled data for the
next entry and treat it incorrectly.  This resulted in wrong kernel
symbols because the kernel DSO loaded a random vmlinux image in the
path as it didn't have a valid build-id.

Fixes: ae39ba16554e ("perf inject: Fix build ID injection")
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/Z0aRFFW9xMh3mqKB@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/build-id.c

index 8982f68e7230cd6433b59f3e1abe2cdd1643304c..e763e8d99a4367d7f35114523169f52317c39635 100644 (file)
@@ -277,7 +277,7 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid
        struct perf_record_header_build_id b;
        size_t len;
 
-       len = sizeof(b) + name_len + 1;
+       len = name_len + 1;
        len = PERF_ALIGN(len, sizeof(u64));
 
        memset(&b, 0, sizeof(b));
@@ -286,7 +286,7 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid
        misc |= PERF_RECORD_MISC_BUILD_ID_SIZE;
        b.pid = pid;
        b.header.misc = misc;
-       b.header.size = len;
+       b.header.size = sizeof(b) + len;
 
        err = do_write(fd, &b, sizeof(b));
        if (err < 0)