summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2026-06-07 22:43:09 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-10 18:56:01 -0300
commit51cdb188edeaf389e4377859b9c483c19ce5a259 (patch)
tree70c7836ae6a822b27223793c8b2b065007c26630
parent1b4e9fbdeabc549965e70ac0cd8095d57ff6df06 (diff)
perf tools: Fix uninitialized pathname on uncompressed fallback in filename__decompress()
filename__decompress() has an early return path for files that are not actually compressed. This path returns the fd from open() directly but never writes to the pathname output parameter, leaving the caller with an uninitialized buffer despite a successful return. Callers like dso__decompress_kmodule_path() pass pathname to decompress_kmodule() which uses it to set the decompressed file path. If pathname is uninitialized, subsequent operations on the path produce undefined behavior. Fix by setting pathname to an empty string on the uncompressed path. Callers already check for an empty pathname to distinguish temporary decompressed files (which need unlink) from the original file. Reported-by: sashiko-bot <sashiko-bot@kernel.org> Fixes: 7ac22b088afe26a4 ("perf tools: Add filename__decompress function") Cc: Jiri Olsa <jolsa@kernel.org> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/tests/code-reading.c7
-rw-r--r--tools/perf/util/disasm.c7
-rw-r--r--tools/perf/util/dso.c12
-rw-r--r--tools/perf/util/symbol-elf.c6
4 files changed, 23 insertions, 9 deletions
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 47043a3a2fb4..e82ecdc95777 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -471,8 +471,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
goto out;
}
- decomp = true;
- objdump_name = decomp_name;
+ /* empty pathname means file wasn't actually compressed */
+ if (decomp_name[0] != '\0') {
+ decomp = true;
+ objdump_name = decomp_name;
+ }
}
/* Read the object code using objdump */
diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
index 59ba88e1f744..0a1a7e9cf3ef 100644
--- a/tools/perf/util/disasm.c
+++ b/tools/perf/util/disasm.c
@@ -1577,8 +1577,11 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
if (dso__decompress_kmodule_path(dso, symfs_filename, tmp, sizeof(tmp)) < 0)
return -1;
- decomp = true;
- strcpy(symfs_filename, tmp);
+ /* empty pathname means file wasn't actually compressed */
+ if (tmp[0] != '\0') {
+ decomp = true;
+ strcpy(symfs_filename, tmp);
+ }
}
/*
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index ee06a252a54d..6a34717c9f31 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -343,8 +343,11 @@ int filename__decompress(const char *name, char *pathname,
* To keep this transparent, we detect this and return the file
* descriptor to the uncompressed file.
*/
- if (!compressions[comp].is_compressed(name))
+ if (!compressions[comp].is_compressed(name)) {
+ if (pathname && len > 0)
+ pathname[0] = '\0';
return open(name, O_RDONLY | O_CLOEXEC);
+ }
fd = mkostemp(tmpbuf, O_CLOEXEC);
if (fd < 0) {
@@ -598,8 +601,11 @@ static char *dso__get_filename(struct dso *dso, const char *root_dir,
goto out;
}
- *decomp = true;
- strcpy(name, newpath);
+ /* empty pathname means file wasn't actually compressed */
+ if (newpath[0] != '\0') {
+ *decomp = true;
+ strcpy(name, newpath);
+ }
}
return name;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 06cfb84f86eb..10902a5dc6db 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -920,12 +920,14 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
return -1;
}
close(fd);
- filename = path;
+ /* non-empty path means a temp file was created */
+ if (path[0] != '\0')
+ filename = path;
}
err = read_build_id(filename, bid);
- if (m.comp)
+ if (m.comp && filename == path)
unlink(filename);
return err;
}