From owner-svn-src-head@freebsd.org Sat Dec 1 20:39:22 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EBC65132706C; Sat, 1 Dec 2018 20:39:21 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 92CF973533; Sat, 1 Dec 2018 20:39:21 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 601571CC85; Sat, 1 Dec 2018 20:39:21 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wB1KdLhq065641; Sat, 1 Dec 2018 20:39:21 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wB1KdLE4065640; Sat, 1 Dec 2018 20:39:21 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201812012039.wB1KdLE4065640@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Sat, 1 Dec 2018 20:39:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341387 - head/lib/libc/gen X-SVN-Group: head X-SVN-Commit-Author: jhibbits X-SVN-Commit-Paths: head/lib/libc/gen X-SVN-Commit-Revision: 341387 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 92CF973533 X-Spamd-Result: default: False [0.62 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_SPAM_LONG(0.31)[0.307,0]; NEURAL_SPAM_MEDIUM(0.10)[0.096,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_SPAM_SHORT(0.22)[0.218,0] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 Dec 2018 20:39:22 -0000 Author: jhibbits Date: Sat Dec 1 20:39:20 2018 New Revision: 341387 URL: https://svnweb.freebsd.org/changeset/base/341387 Log: Fix PowerPC64 ELFv1-specific problem in __elf_phdr_match_addr() leading to crash in threaded programs that unload libraries. Summary: The GNOME update to 3.28 exposed a bug in __elf_phdr_match_addr(), which leads to a crash when building devel/libsoup on powerpc64. Due to __elf_phdr_match_addr() limiting its search to PF_X sections, on the PPC64 ELFv1 ABI, it was never matching function pointers properly. This meant that libthr was never cleaning up its atfork list in __pthread_cxa_finalize(), so if a library with an atfork handler was unloaded, libthr would crash on the next fork. Normally, the null pointer check it does before calling the handler would avoid this crash, but, due to PPC64 ELFv1 using function descriptors instead of raw function pointers, a null check against the pointer itself is insufficient, as the pointer itself was not null, it was just pointing at a function descriptor that had been zeroed. (Which is an ABI violation.) Calling a zeroed function descriptor on PPC64 ELFv1 causes a jump to address 0 with a zeroed r2 and r11. Submitted by: git_bdragon.rtk0.net Reviewed By: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D18364 Modified: head/lib/libc/gen/elf_utils.c Modified: head/lib/libc/gen/elf_utils.c ============================================================================== --- head/lib/libc/gen/elf_utils.c Sat Dec 1 20:31:49 2018 (r341386) +++ head/lib/libc/gen/elf_utils.c Sat Dec 1 20:39:20 2018 (r341387) @@ -47,8 +47,21 @@ __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, for (i = 0; i < phdr_info->dlpi_phnum; i++) { ph = &phdr_info->dlpi_phdr[i]; - if (ph->p_type != PT_LOAD || (ph->p_flags & PF_X) == 0) + if (ph->p_type != PT_LOAD) continue; + + /* ELFv1 ABI for powerpc64 passes function descriptor + * pointers around, not function pointers. The function + * descriptors live in .opd, which is a non-executable segment. + * The PF_X check would therefore make all address checks fail, + * causing a crash in some instances. Don't skip over + * non-executable segments in the ELFv1 powerpc64 case. + */ +#if !defined(__powerpc64__) || (defined(_CALL_ELF) && _CALL_ELF == 2) + if ((ph->p_flags & PF_X) == 0) + continue; +#endif + if (phdr_info->dlpi_addr + ph->p_vaddr <= (uintptr_t)addr && (uintptr_t)addr + sizeof(addr) < phdr_info->dlpi_addr + ph->p_vaddr + ph->p_memsz)