From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/11950 Path: news.gmane.org!.POSTED!not-for-mail From: John Reiser Newsgroups: gmane.linux.lib.musl.general Subject: preventable SIGSEGV when bad AT_SYSINFO_EHDR Date: Tue, 19 Sep 2017 09:46:19 -0700 Message-ID: <439c3bd7-9eed-dd18-a025-bd6257373f11@bitwagon.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: blaine.gmane.org 1505839604 21238 195.159.176.226 (19 Sep 2017 16:46:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 19 Sep 2017 16:46:44 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 To: musl@lists.openwall.com Original-X-From: musl-return-11963-gllmg-musl=m.gmane.org@lists.openwall.com Tue Sep 19 18:46:39 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1duLfQ-00055x-FC for gllmg-musl@m.gmane.org; Tue, 19 Sep 2017 18:46:36 +0200 Original-Received: (qmail 27650 invoked by uid 550); 19 Sep 2017 16:46:39 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 26592 invoked from network); 19 Sep 2017 16:46:38 -0000 Content-Language: en-US Xref: news.gmane.org gmane.linux.lib.musl.general:11950 Archived-At: __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 --