From patchwork Sat May 14 23:14:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 12261 Received: (qmail 44850 invoked by alias); 14 May 2016 23:14:42 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 43659 invoked by uid 89); 14 May 2016 23:14:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=faults X-HELO: mtlfep01.bell.net From: John David Anglin Mime-Version: 1.0 (Apple Message framework v1085) Date: Sat, 14 May 2016 19:14:27 -0400 Subject: [PATCH: hppa] Fix segmentation faults in _dl_lookup_address Cc: Carlos O'Donell , Mike Frysinger To: GNU C Library Message-Id: X-Opwv-CommTouchExtSvcRefID: str=0001.0A020204.5737B154.004E, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 The attached change fixes a regression in the debug/backtrace-tst test. It tightens up the checks for a valid function pointers. It also uses the proberi instruction to avoid faulting when the address is not a valid function pointer. However, it's probably not possible to completely ensure that the address lookup is correct given an arbitrary address. Please install if okay. Dave --- John David Anglin dave.anglin@bell.net 2016-05-14 John David Anglin [BZ 20098] * sysdeps/hppa/dl-fptr.c (_dl_read_access_allowed): New. (_dl_lookup_address): Return address if it is not consistent with being a linker defined function pointer. Likewise, return address if address and function descriptor addresses are not accessible. diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c index 083242b..af0c5a1 100644 --- a/sysdeps/hppa/dl-fptr.c +++ b/sysdeps/hppa/dl-fptr.c @@ -331,22 +331,45 @@ elf_machine_resolve (void) return addr; } +static inline int +_dl_read_access_allowed (unsigned int *addr) +{ + int result; + + asm ("proberi (%1),3,%0" : "=r" (result) : "r" (addr) : ); + + return result; +} + ElfW(Addr) _dl_lookup_address (const void *address) { ElfW(Addr) addr = (ElfW(Addr)) address; unsigned int *desc, *gptr; - /* Check for special cases. */ - if ((int) addr == -1 - || (unsigned int) addr < 4096 - || !((unsigned int) addr & 2)) + /* Return ADDR if the least-significant two bits of ADDR are not consistent + with ADDR being a linker defined function pointer. The normal value for + a code address in a backtrace is 3. */ + if (((unsigned int) addr & 3) != 2) + return addr; + + /* Handle special case where ADDR points to page 0. */ + if ((unsigned int) addr < 4096) return addr; /* Clear least-significant two bits from descriptor address. */ desc = (unsigned int *) ((unsigned int) addr & ~3); + if (!_dl_read_access_allowed (desc)) + return addr; + + /* Load first word of candidate descriptor. It should be a pointer + with word alignment and point to memory that can be read. */ + gptr = (unsigned int *) desc[0]; + if (((unsigned int) gptr & 3) != 0 + || !_dl_read_access_allowed (gptr)) + return addr; - /* Check if descriptor requires resolution. The following trampoline is + /* See if descriptor requires resolution. The following trampoline is used in each global offset table for function resolution: ldw 0(r20),r22 @@ -358,7 +381,6 @@ _dl_lookup_address (const void *address) .word "_dl_runtime_resolve ltp" got: .word _DYNAMIC .word "struct link map address" */ - gptr = (unsigned int *) desc[0]; if (gptr[0] == 0xea9f1fdd /* b,l .-12,r20 */ && gptr[1] == 0xd6801c1e /* depwi 0,31,2,r20 */ && (ElfW(Addr)) gptr[2] == elf_machine_resolve ())