|
|
Message-ID: <439c3bd7-9eed-dd18-a025-bd6257373f11@bitwagon.com>
Date: Tue, 19 Sep 2017 09:46:19 -0700
From: John Reiser <jreiser@...wagon.com>
To: musl@...ts.openwall.com
Subject: preventable SIGSEGV when bad AT_SYSINFO_EHDR
__dls3() and friends in musl/ldso/dynlink.c should check Elf headers more carefully.
I saw a SIGSEGV in decode_dyn() because vdso_base = ElfXX_auxv[{AT_SYSINFO_EHDR}].a_ptr
pointed to a region that was all zero, and thus vdso.dynv == 0. The operating system
kernel is the only one who can perform a fork() or clone(), but other software can
perform execve(). In my case that other software had a bug. However, the blame
for the SIGSEGV rests on __dls3() because it did not validate input data. [This is
the stuff of exploits.] Calling a_crash() is OK; but a preventable SIGSEGV must be
avoided, both directly and because it indicates a lack of secure implementation.
It is [mostly] reasonable that __dls3() should trust that a non-zero vdso_base points to
a region that is readable, is as big and as aligned as an ElfXX_Ehdr, and is const
(no other thread is writing it, neither is any other process via a shared memory mapping);
but after that ldso should check.
In particular, these should be checked:
0 == memcmp(ELFMAG, &.e_ident[EI_MAG0], SELFMAG)
.e_machine matches the executing ldso
.e_ident[{EI_CLASS, EI_DATA}] match the executing ldso
.e_phnum != 0
.e_phentsize >= sizeof(ElfXX_Phdr); and larger *IS ALLOWED*: derived classes, etc.
.e_phnum * .e_phentsize is not too large [loops that increment a pointer by .e_phentsize]
.e_phoff >= sizeof(ElfXX_Ehdr); overlap of Ehdr and Phdr is a logical error
(.e_phoff + .e_phnum * .e_phentsize) < .st_size; no access beyond EOF
--
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.