From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 8EC983858004 for ; Tue, 16 Mar 2021 10:11:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8EC983858004 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-395-mET9dHwkNR-0F8HObmZtQA-1; Tue, 16 Mar 2021 06:11:21 -0400 X-MC-Unique: mET9dHwkNR-0F8HObmZtQA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CE13E108BD08 for ; Tue, 16 Mar 2021 10:11:20 +0000 (UTC) Received: from oldenburg.str.redhat.com (ovpn-112-163.ams2.redhat.com [10.36.112.163]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F3B7C6C330 for ; Tue, 16 Mar 2021 10:11:19 +0000 (UTC) From: Florian Weimer To: libc-stable@sourceware.org Subject: [PATCH COMMITTED 2.33] elf: Always set l in _dl_init_paths (bug 23462) Date: Tue, 16 Mar 2021 11:11:27 +0100 Message-ID: <87blbjqugg.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-stable@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-stable mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Mar 2021 10:11:27 -0000 From: Carlos O'Donell After d1d5471579eb0426671bf94f2d71e61dfb204c30 ("Remove dead DL_DST_REQ_STATIC code.") we always setup the link map l to make the static and shared cases the same. The bug is that in elf/dl-load.c (_dl_init_paths) we conditionally set l only in the #ifdef SHARED case, but unconditionally use it later. The simple solution is to remove the #ifdef SHARED conditional, because it's no longer needed, and unconditionally setup l for both the static and shared cases. A regression test is added to run a static binary with LD_LIBRARY_PATH='$ORIGIN' which crashes before the fix and runs after the fix. Co-Authored-By: Florian Weimer (cherry picked from commit 332421312576bd7095e70589154af99b124dd2d1) --- NEWS | 4 ++++ elf/Makefile | 5 ++++- elf/dl-load.c | 63 ++++++++++++++++++++++++---------------------------- elf/tst-dst-static.c | 32 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/NEWS b/NEWS index 11cd7c7069..abc4206f58 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ Major new features: a dump of information related to IFUNC resolver operation and glibc-hwcaps subdirectory selection. +The following bugs are resolved with this release: + + [23462] Static binary with dynamic string tokens ($LIB, $PLATFORM, $ORIGIN) + crashes Version 2.33 diff --git a/elf/Makefile b/elf/Makefile index 7610fa080f..63da0ed64f 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -164,7 +164,8 @@ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \ tst-dl-iter-static \ tst-tlsalign-static tst-tlsalign-extern-static \ tst-linkall-static tst-env-setuid tst-env-setuid-tunables \ - tst-single_threaded-static tst-single_threaded-pthread-static + tst-single_threaded-static tst-single_threaded-pthread-static \ + tst-dst-static tests-static-internal := tst-tls1-static tst-tls2-static \ tst-ptrguard1-static tst-stackguard1-static \ @@ -1905,3 +1906,5 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so cmp tst-rtld-list-tunables.exp \ $(objpfx)/tst-rtld-list-tunables.out > $@; \ $(evaluate-test) + +tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN' diff --git a/elf/dl-load.c b/elf/dl-load.c index 9e2089cfaa..376a2e64d6 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -758,50 +758,45 @@ _dl_init_paths (const char *llp, const char *source, max_dirnamelen = SYSTEM_DIRS_MAX_LEN; *aelem = NULL; -#ifdef SHARED /* This points to the map of the main object. */ l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - if (l != NULL) + assert (l->l_type != lt_loaded); + + if (l->l_info[DT_RUNPATH]) + { + /* Allocate room for the search path and fill in information + from RUNPATH. */ + decompose_rpath (&l->l_runpath_dirs, + (const void *) (D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[DT_RUNPATH]->d_un.d_val), + l, "RUNPATH"); + /* During rtld init the memory is allocated by the stub malloc, + prevent any attempt to free it by the normal malloc. */ + l->l_runpath_dirs.malloced = 0; + + /* The RPATH is ignored. */ + l->l_rpath_dirs.dirs = (void *) -1; + } + else { - assert (l->l_type != lt_loaded); + l->l_runpath_dirs.dirs = (void *) -1; - if (l->l_info[DT_RUNPATH]) + if (l->l_info[DT_RPATH]) { /* Allocate room for the search path and fill in information - from RUNPATH. */ - decompose_rpath (&l->l_runpath_dirs, + from RPATH. */ + decompose_rpath (&l->l_rpath_dirs, (const void *) (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_RUNPATH]->d_un.d_val), - l, "RUNPATH"); - /* During rtld init the memory is allocated by the stub malloc, - prevent any attempt to free it by the normal malloc. */ - l->l_runpath_dirs.malloced = 0; - - /* The RPATH is ignored. */ - l->l_rpath_dirs.dirs = (void *) -1; + + l->l_info[DT_RPATH]->d_un.d_val), + l, "RPATH"); + /* During rtld init the memory is allocated by the stub + malloc, prevent any attempt to free it by the normal + malloc. */ + l->l_rpath_dirs.malloced = 0; } else - { - l->l_runpath_dirs.dirs = (void *) -1; - - if (l->l_info[DT_RPATH]) - { - /* Allocate room for the search path and fill in information - from RPATH. */ - decompose_rpath (&l->l_rpath_dirs, - (const void *) (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_RPATH]->d_un.d_val), - l, "RPATH"); - /* During rtld init the memory is allocated by the stub - malloc, prevent any attempt to free it by the normal - malloc. */ - l->l_rpath_dirs.malloced = 0; - } - else - l->l_rpath_dirs.dirs = (void *) -1; - } + l->l_rpath_dirs.dirs = (void *) -1; } -#endif /* SHARED */ if (llp != NULL && *llp != '\0') { diff --git a/elf/tst-dst-static.c b/elf/tst-dst-static.c new file mode 100644 index 0000000000..56eb371c96 --- /dev/null +++ b/elf/tst-dst-static.c @@ -0,0 +1,32 @@ +/* Test DST expansion for static binaries doesn't carsh. Bug 23462. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* The purpose of this test is to exercise the code in elf/dl-loac.c + (_dl_init_paths) or thereabout and ensure that static binaries + don't crash when expanding DSTs. + + If the dynamic loader code linked into the static binary cannot + handle expanding the DSTs e.g. null-deref on an incomplete link + map, then it will crash before reaching main, so the test harness + is unnecessary. */ + +int +main (void) +{ + return 0; +}