Commit e99d544c authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarIan 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 92d65d9c
Loading
Loading
Loading
Loading
+21 −10
Original line number Diff line number Diff line
@@ -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) {
		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) {
			unsigned char eidata;

			if (pread(fd, &eidata, sizeof(eidata), EI_DATA) == sizeof(eidata))
				dso__swap_init(dso, eidata);
		}
			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))
			    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;
		}
	}
	mutex_unlock(dso__data_open_lock());
	return e_machine;