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 <[email protected]>
---
 tools/perf/util/dso.c | 31 +++++++++++++++++++++----------
 1 file 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;
-- 
2.52.0.457.g6b5491de43-goog


Reply via email to