From patchwork Tue Aug 6 08:48:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 95353 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DBA3D385E82F for ; Tue, 6 Aug 2024 08:49:02 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 55FAE385B50B for ; Tue, 6 Aug 2024 08:48:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 55FAE385B50B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 55FAE385B50B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934111; cv=none; b=gTO9iG3XM6nriJWrgujZI+yNx9G6uRa3nnbB/FfmZlP2ASB1hzB2iqRpwLauMauoBUyr7SzedqMSj4Z3/SJv563vyFmMmHXuTrg+j0CBZ2CtRJdVbT1+7uzJQoQamput2c0JVNMurSn4c/0M6dymiHey/knGjkI7nUrToqDJyW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934111; c=relaxed/simple; bh=1uJdK546IEQeeepS1osyjftDLrk3K475BWGLXkUCOV0=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=tzWFFztqAr1bJu4fYfEZxvUUCV0+x72WqmngWiXQU9Xfvc0QX958SGNK7QEaljoZe16wWGAeTxRHUASbzEj1ucfn+iQskxWwWjVX2B7HbotmffzAml5yIejD1QWAVxUbslpYIjlMKGjPQQQIuIPQ0mei9pmWZHGZ1+5tJZIZi74= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722934109; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=x09omEP+qYdYU8etGqkpzKL1LUaRuoLUVXYtlm4TfYs=; b=YdPGeqhkuAwP7kXxgS0ct/TBKuayqNjBTuCO5ncwOCJN9vubQLAnTphwqyhad24Eha4ksB VjEwPwPbGHXjqm6ASi4dwXy4Tp4/syKxxjOswSE2ogRpww6tP1SgAiEg5y+A0dGE1CFphD Es68IKw+sjVOrvxNOuMfFemks08ylHs= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-642-1FOoqediMuWEhAx74ojn4A-1; Tue, 06 Aug 2024 04:48:26 -0400 X-MC-Unique: 1FOoqediMuWEhAx74ojn4A-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2795A1955D50 for ; Tue, 6 Aug 2024 08:48:26 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.45.224.40]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 15D521955F40 for ; Tue, 6 Aug 2024 08:48:24 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 1/3] elf: rtld_multiple_ref is always true In-Reply-To: Message-ID: References: X-From-Line: e31d7f5a97ff53ed9764e1655212bf345708f88b Mon Sep 17 00:00:00 2001 Date: Tue, 06 Aug 2024 10:48:21 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org For a long time, libc.so.6 has dependend on ld.so, which means that there is a reference to ld.so in all processes, and rtld_multiple_ref is always true. In fact, if rtld_multiple_ref were false, some of the ld.so setup code would not run. --- elf/rtld.c | 104 +++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/elf/rtld.c b/elf/rtld.c index 09b9c9993b..cc4f3e51f9 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1983,43 +1983,37 @@ dl_main (const ElfW(Phdr) *phdr, if (main_map->l_searchlist.r_list[i] == &GL(dl_rtld_map)) break; - bool rtld_multiple_ref = false; - if (__glibc_likely (i < main_map->l_searchlist.r_nlist)) - { - /* Some DT_NEEDED entry referred to the interpreter object itself, so - put it back in the list of visible objects. We insert it into the - chain in symbol search order because gdb uses the chain's order as - its symbol search order. */ - rtld_multiple_ref = true; + /* Insert the link map for the dynamic loader into the chain in + symbol search order because gdb uses the chain's order as its + symbol search order. */ - GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; - if (__glibc_likely (state.mode == rtld_mode_normal)) - { - GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist - ? main_map->l_searchlist.r_list[i + 1] - : NULL); + GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; + if (__glibc_likely (state.mode == rtld_mode_normal)) + { + GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist + ? main_map->l_searchlist.r_list[i + 1] + : NULL); #ifdef NEED_DL_SYSINFO_DSO - if (GLRO(dl_sysinfo_map) != NULL - && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) - && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) - GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); + if (GLRO(dl_sysinfo_map) != NULL + && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) + && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) + GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); #endif - } - else - /* In trace mode there might be an invisible object (which we - could not find) after the previous one in the search list. - In this case it doesn't matter much where we put the - interpreter object, so we just initialize the list pointer so - that the assertion below holds. */ - GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; - - assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); - GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); - if (GL(dl_rtld_map).l_next != NULL) - { - assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); - GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); - } + } + else + /* In trace mode there might be an invisible object (which we + could not find) after the previous one in the search list. + In this case it doesn't matter much where we put the + interpreter object, so we just initialize the list pointer so + that the assertion below holds. */ + GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; + + assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); + GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); + if (GL(dl_rtld_map).l_next != NULL) + { + assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); + GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); } /* Now let us see whether all libraries are available in the @@ -2347,35 +2341,33 @@ dl_main (const ElfW(Phdr) *phdr, /* Make sure no new search directories have been added. */ assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); - if (rtld_multiple_ref) - { - /* There was an explicit ref to the dynamic linker as a shared lib. - Re-relocate ourselves with user-controlled symbol definitions. + /* Re-relocate ourselves with user-controlled symbol definitions. - We must do this after TLS initialization in case after this - re-relocation, we might call a user-supplied function - (e.g. calloc from _dl_relocate_object) that uses TLS data. */ + We must do this after TLS initialization in case after this + re-relocation, we might call a user-supplied function + (e.g. calloc from _dl_relocate_object) that uses TLS data. */ - /* Set up the object lookup structures. */ - _dl_find_object_init (); + /* Set up the object lookup structures. */ + _dl_find_object_init (); - /* The malloc implementation has been relocated, so resolving - its symbols (and potentially calling IFUNC resolvers) is safe - at this point. */ - __rtld_malloc_init_real (main_map); + /* The malloc implementation has been relocated, so resolving + its symbols (and potentially calling IFUNC resolvers) is safe + at this point. */ + __rtld_malloc_init_real (main_map); - /* Likewise for the locking implementation. */ - __rtld_mutex_init (); + /* Likewise for the locking implementation. */ + __rtld_mutex_init (); - RTLD_TIMING_VAR (start); - rtld_timer_start (&start); + { + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); - /* Mark the link map as not yet relocated again. */ - GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); + /* Mark the link map as not yet relocated again. */ + GL(dl_rtld_map).l_relocated = 0; + _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); - rtld_timer_accum (&relocate_time, start); - } + rtld_timer_accum (&relocate_time, start); + } /* Relocation is complete. Perform early libc initialization. This is the initial libc, even if audit modules have been loaded with From patchwork Tue Aug 6 08:48:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 95354 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A14A4385E45D for ; Tue, 6 Aug 2024 08:49:09 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id D00AE385DDD1 for ; Tue, 6 Aug 2024 08:48:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D00AE385DDD1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D00AE385DDD1 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934116; cv=none; b=eJwfo0meRBQH6844g623usFao0LQGdj5+9Ga8g3VJvaDrMn7W3PAiOzN5noJt/wWb37GzfEcMMuck5ZdinGDKJatMt3ALX1Q0EQqmy3ycCwolaD7BVmnBcm4xY3hbkee5TSqgppMZ12Py5sQbCDOQiJ4UgQSSgAuekk+wz1ToOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934116; c=relaxed/simple; bh=us6p72EJWxirs8cwO+JgQPUzTf6pJOyav3/g9vJBa7c=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=Ka9IFR0lfpP8nhNrwXeBTPPyo+YxbkH5drpc6TsyKNMEObFPJAoqfQsrI72o7ZZMFbEklXuQgRZcZNrt7tMKx0ZN2twqsgA6p4dNEdVDx7E56nSCBY6YQ0uWA/kdjo21u7KAjuEfuVYCoVAkBPwrn7c6AkucebDxo1xcxHqIl6w= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722934114; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=FKQ2DRPpzprXbjuCOO/BR6NYyoWEnaeM7nivSH9A0rA=; b=RnJOUn9ZyiBkn9YrIl+ic8nJPg0hcleUwTHBS47PlqY3WJMf/Kh4gMpSus46w10kiGAt4C DIGYwAYXUePv2/8Yd0L7CL+VRfGfzWActg0yRSSvt2lvD2C9wGyK+od6bNSS0t4N90oFXV wBo89MiY/09tq1eDn8gYTMnhepLICjY= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-214-Q-ijACm4MnO4yVlRwNrAwA-1; Tue, 06 Aug 2024 04:48:32 -0400 X-MC-Unique: Q-ijACm4MnO4yVlRwNrAwA-1 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D29571955D59 for ; Tue, 6 Aug 2024 08:48:31 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.45.224.40]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 083DB3001D83 for ; Tue, 6 Aug 2024 08:48:30 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 2/3] elf: Introduce _dl_relocate_object_no_relro In-Reply-To: Message-ID: <200b2c6531a6a325c0b8824fe411ee70e622ed2f.1722934012.git.fweimer@redhat.com> References: X-From-Line: 200b2c6531a6a325c0b8824fe411ee70e622ed2f Mon Sep 17 00:00:00 2001 Date: Tue, 06 Aug 2024 10:48:27 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org And make _dl_protect_relro apply RELRO conditionally. --- elf/dl-reloc.c | 24 ++++++++++++++---------- sysdeps/generic/ldsodefs.h | 7 +++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 4bf7aec88b..bdb271fdfc 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -202,12 +202,9 @@ resolve_map (lookup_t l, struct r_scope_elem *scope[], const ElfW(Sym) **ref, #include "dynamic-link.h" void -_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], - int reloc_mode, int consider_profiling) +_dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[], + int reloc_mode, int consider_profiling) { - if (l->l_relocated) - return; - struct textrels { caddr_t start; @@ -342,17 +339,24 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], textrels = textrels->next; } - - /* In case we can protect the data now that the relocations are - done, do it. */ - if (l->l_relro_size != 0) - _dl_protect_relro (l); } +void +_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + int reloc_mode, int consider_profiling) +{ + if (l->l_relocated) + return; + _dl_relocate_object_no_relro (l, scope, reloc_mode, consider_profiling); + _dl_protect_relro (l); +} void _dl_protect_relro (struct link_map *l) { + if (l->l_relro_size == 0) + return; + ElfW(Addr) start = ALIGN_DOWN((l->l_addr + l->l_relro_addr), GLRO(dl_pagesize)); diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 259ce2e7d6..91447a5e77 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1014,6 +1014,13 @@ extern void _dl_relocate_object (struct link_map *map, int reloc_mode, int consider_profiling) attribute_hidden; +/* Perform relocation, but do not apply RELRO. Does not check + L->relocated. Otherwise the same as _dl_relocate_object. */ +void _dl_relocate_object_no_relro (struct link_map *map, + struct r_scope_elem *scope[], + int reloc_mode, int consider_profiling) + attribute_hidden; + /* Protect PT_GNU_RELRO area. */ extern void _dl_protect_relro (struct link_map *map) attribute_hidden; From patchwork Tue Aug 6 08:48:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 95355 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DB66B385EC59 for ; Tue, 6 Aug 2024 08:49:12 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 36C193858C66 for ; Tue, 6 Aug 2024 08:48:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 36C193858C66 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 36C193858C66 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934124; cv=none; b=gvmYW2j2oiLQg+K7yCYC1zv9dBNKPj9wgnefYpcBdxD4lLsN1rUgMNwUnMtKUvu643tWa1Zkp2sePlgyXrbU9QQ/FHbXy73UXoSBUoRnzNrIyjx7cZZdDxdc5/+7UCML2spAzL8ee9NQ7mtFp+3A+OTO+IMrjTJSdfxR+C3ZdbY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722934124; c=relaxed/simple; bh=UVXygLCKGXKMH7dMahSNw1ix0pVUzSy2qlequPSzD58=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=te3p0x0wyd3Bj5hJrXgNFOdj30bCePKC3bMENboUV/2w/ZSN0tuSE0OZtJaK+59aVCnzOxD2E1wYv9TWhquPM8jFvQTgryl46hzx5xxpvlD8oXUCvIpy0sA/3lWccVOaqZTQQeTiYh++idtn9qad2qcGd0i51qNKOcpxXmLbZYA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722934121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=wDWoZhsf2UrW4rQV2yieh86/bz2GB1TfhU0pEEKS1Ak=; b=VEWP5LFJSJLHmehgfWhn9a17HYHZ9SDtFP3H/KdMlc197ebHXifHlwQ13jj6JRwghmWtMa xbOj4/YOXSAS+9J8NPbINf5hRfGrM5ssgdWnyeWLnxuU1+cgPzGobt/0zftnBS+ECfG2A1 ZOazfYCm3x+vLVug0X3iZmVNl7xBKXQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-536-m3HJnpbCP_-oCsBku4HohA-1; Tue, 06 Aug 2024 04:48:39 -0400 X-MC-Unique: m3HJnpbCP_-oCsBku4HohA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9C6A51955F43 for ; Tue, 6 Aug 2024 08:48:38 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.45.224.40]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A8A751955F40 for ; Tue, 6 Aug 2024 08:48:37 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 3/3] elf: Switch to main malloc after final ld.so self-relocation In-Reply-To: Message-ID: <61844731147e785796f487d75519012bf50124c2.1722934012.git.fweimer@redhat.com> References: X-From-Line: 61844731147e785796f487d75519012bf50124c2 Mon Sep 17 00:00:00 2001 Date: Tue, 06 Aug 2024 10:48:34 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Before commit ee1ada1bdb8074de6e1bdc956ab19aef7b6a7872 ("elf: Rework exception handling in the dynamic loader [BZ #25486]"), the previous order called the main calloc to allocate a shadow GOT/PLT array for auditing support. This happened before libc.so.6 ELF constructors were run, so a user malloc could run without libc.so.6 having been initialized fully. One observable effect was that environ was NULL at this point. It does not seem to be possible at present to trigger such an allocation, but it seems more robust to delay switching to main malloc after ld.so self-relocation is complete. The elf/tst-rtld-no-malloc-audit test case fails with a 2.34-era glibc that does not have this fix. --- elf/Makefile | 9 ++++ elf/dl-support.c | 3 +- elf/rtld.c | 26 +++++------ elf/tst-rtld-no-malloc-audit.c | 1 + elf/tst-rtld-no-malloc-preload.c | 1 + elf/tst-rtld-no-malloc.c | 75 ++++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 elf/tst-rtld-no-malloc-audit.c create mode 100644 elf/tst-rtld-no-malloc-preload.c create mode 100644 elf/tst-rtld-no-malloc.c diff --git a/elf/Makefile b/elf/Makefile index a03c6520d8..f34febfa5b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -452,6 +452,9 @@ tests += \ tst-recursive-tls \ tst-relsort1 \ tst-ro-dynamic \ + tst-rtld-no-malloc \ + tst-rtld-no-malloc-audit \ + tst-rtld-no-malloc-preload \ tst-rtld-run-static \ tst-single_threaded \ tst-single_threaded-pthread \ @@ -3148,3 +3151,9 @@ $(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so tst-dlopen-tlsreinit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so $(objpfx)tst-dlopen-tlsreinit4.out: $(objpfx)tst-auditmod1.so tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + +# Reuse an audit module which provides ample debug logging. +tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + +# Any shared object should do. +tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so diff --git a/elf/dl-support.c b/elf/dl-support.c index 451932dd03..ee590edf93 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -338,8 +338,7 @@ _dl_non_dynamic_init (void) call_function_static_weak (_dl_find_object_init); /* Setup relro on the binary itself. */ - if (_dl_main_map.l_relro_size != 0) - _dl_protect_relro (&_dl_main_map); + _dl_protect_relro (&_dl_main_map); } #ifdef DL_SYSINFO_IMPLEMENTATION diff --git a/elf/rtld.c b/elf/rtld.c index cc4f3e51f9..1e6c506634 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -2341,34 +2341,32 @@ dl_main (const ElfW(Phdr) *phdr, /* Make sure no new search directories have been added. */ assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); - /* Re-relocate ourselves with user-controlled symbol definitions. - - We must do this after TLS initialization in case after this - re-relocation, we might call a user-supplied function - (e.g. calloc from _dl_relocate_object) that uses TLS data. */ - /* Set up the object lookup structures. */ _dl_find_object_init (); - /* The malloc implementation has been relocated, so resolving - its symbols (and potentially calling IFUNC resolvers) is safe - at this point. */ - __rtld_malloc_init_real (main_map); - /* Likewise for the locking implementation. */ __rtld_mutex_init (); + /* Re-relocate ourselves with user-controlled symbol definitions. */ + { RTLD_TIMING_VAR (start); rtld_timer_start (&start); - /* Mark the link map as not yet relocated again. */ - GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); + _dl_relocate_object_no_relro (&GL(dl_rtld_map), main_map->l_scope, 0, 0); + + /* The malloc implementation has been relocated, so resolving + its symbols (and potentially calling IFUNC resolvers) is safe + at this point. */ + __rtld_malloc_init_real (main_map); + + if (GL(dl_rtld_map).l_relro_size != 0) + _dl_protect_relro (&GL(dl_rtld_map)); rtld_timer_accum (&relocate_time, start); } + /* Relocation is complete. Perform early libc initialization. This is the initial libc, even if audit modules have been loaded with other libcs. */ diff --git a/elf/tst-rtld-no-malloc-audit.c b/elf/tst-rtld-no-malloc-audit.c new file mode 100644 index 0000000000..a028377ad1 --- /dev/null +++ b/elf/tst-rtld-no-malloc-audit.c @@ -0,0 +1 @@ +#include "tst-rtld-no-malloc.c" diff --git a/elf/tst-rtld-no-malloc-preload.c b/elf/tst-rtld-no-malloc-preload.c new file mode 100644 index 0000000000..a028377ad1 --- /dev/null +++ b/elf/tst-rtld-no-malloc-preload.c @@ -0,0 +1 @@ +#include "tst-rtld-no-malloc.c" diff --git a/elf/tst-rtld-no-malloc.c b/elf/tst-rtld-no-malloc.c new file mode 100644 index 0000000000..a78f1ba727 --- /dev/null +++ b/elf/tst-rtld-no-malloc.c @@ -0,0 +1,75 @@ +/* Test that program loading does not call malloc. + Copyright (C) 2024 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 + . */ + + +#include +#include + +static void +print (const char *s) +{ + const char *end = s + strlen (s); + while (s < end) + { + ssize_t ret = write (STDOUT_FILENO, s, end - s); + if (ret <= 0) + _exit (2); + s += ret; + } +} + +static void __attribute__ ((noreturn)) +unexpected_call (const char *function) +{ + print ("error: unexpected call to "); + print (function); + print ("\n"); + _exit (1); +} + +/* These are the malloc functions implement in elf/dl-minimal.c. */ + +void +free (void *ignored) +{ + unexpected_call ("free"); +} + +void * +calloc (size_t ignored1, size_t ignored2) +{ + unexpected_call ("calloc"); +} + +void * +malloc (size_t ignored) +{ + unexpected_call ("malloc"); +} + +void * +realloc (void *ignored1, size_t ignored2) +{ + unexpected_call ("realloc"); +} + +int +main (void) +{ + /* Do not use the test wrapper, to avoid spurious malloc calls from it. */ +}