summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2026-01-17 08:28:28 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-01-20 18:55:01 +0300
commite99d544c7f3691eb321c88fdbadf04b777c114c4 (patch)
tree839ea73f3f70285d3f7d67cff17a66095eec92e7 /tools
parent92d65d9c31621befe0a5f7c0bd43bd217613c6b6 (diff)
downloadlinux-e99d544c7f3691eb321c88fdbadf04b777c114c4.tar.xz
perf dso: Extra validity checks that e_machine is valid
Better ensure a read e_machine is valid by checking the file appears like an ELF file and the read e_machine value is less than EM_NUM. This better avoids spurious e_machine values when looking for an e_machine in say a thread. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Andi Kleen <ak@linux.intel.com> Cc: Athira Rajeev <atrajeev@linux.ibm.com> Cc: Chun-Tse Shao <ctshao@google.com> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Dr. David Alan Gilbert <linux@treblig.org> Cc: Guo Ren <guoren@kernel.org> Cc: Haibo Xu <haibo1.xu@intel.com> Cc: Howard Chu <howardchu95@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Krzysztof Ɓopatowski <krzysztof.m.lopatowski@gmail.com> Cc: Leo Yan <leo.yan@linux.dev> Cc: Mark Wielaard <mark@klomp.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <pjw@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sergei Trofimovich <slyich@gmail.com> Cc: Shimin Guo <shimin.guo@skydio.com> Cc: Stephen Brennan <stephen.s.brennan@oracle.com> Cc: Thomas Falcon <thomas.falcon@intel.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/dso.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 18e656712f5a..143720d1ecb1 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1236,17 +1236,28 @@ uint16_t dso__e_machine(struct dso *dso, struct machine *machine)
try_to_open_dso(dso, machine);
fd = dso__data(dso)->fd;
if (fd >= 0) {
- _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset");
- _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset");
- if (dso__needs_swap(dso) == DSO_SWAP__UNSET) {
- unsigned char eidata;
-
- if (pread(fd, &eidata, sizeof(eidata), EI_DATA) == sizeof(eidata))
- dso__swap_init(dso, eidata);
+ unsigned char e_ident[EI_NIDENT];
+
+ _Static_assert(offsetof(Elf32_Ehdr, e_ident) == 0, "Unexpected offset");
+ _Static_assert(offsetof(Elf64_Ehdr, e_ident) == 0, "Unexpected offset");
+ if (pread(fd, &e_ident, sizeof(e_ident), 0) == sizeof(e_ident) &&
+ memcmp(e_ident, ELFMAG, SELFMAG) == 0 &&
+ e_ident[EI_CLASS] > ELFCLASSNONE && e_ident[EI_CLASS] < ELFCLASSNUM &&
+ e_ident[EI_DATA] > ELFDATANONE && e_ident[EI_DATA] < ELFDATANUM &&
+ e_ident[EI_VERSION] == EV_CURRENT) {
+ _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset");
+ _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset");
+
+ if (dso__needs_swap(dso) == DSO_SWAP__UNSET)
+ dso__swap_init(dso, e_ident[EI_DATA]);
+
+ if (dso__needs_swap(dso) != DSO_SWAP__UNSET &&
+ pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine) &&
+ e_machine < EM_NUM)
+ e_machine = DSO__SWAP(dso, uint16_t, e_machine);
+ else
+ e_machine = EM_NONE;
}
- if (dso__needs_swap(dso) != DSO_SWAP__UNSET &&
- pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine))
- e_machine = DSO__SWAP(dso, uint16_t, e_machine);
}
mutex_unlock(dso__data_open_lock());
return e_machine;