|
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.