From patchwork Wed Dec 2 11:30:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 1409656 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=JjxuBTYq; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmGwz2lVsz9sPB for ; Wed, 2 Dec 2020 22:30:27 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C31C3385780D; Wed, 2 Dec 2020 11:30:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C31C3385780D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1606908622; bh=xkfynwYnPRKHnyjTzBdWL8d+b070YoYAeA+4rCBAQ+o=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=JjxuBTYqD11H4GIXX4iq3/gEa17MJGSQ6pwtjNzlBJTOms9myHtKad9389RzGDG+e gIY2RvglABXHbIuoeyzYW2pFQYxdjkmYNkwMfkJHqY+sTcWeqNdeB+2jEX5TZf89rP F8XlXg/9/qyyFTfcWH/b9JX1Rqti1TnfTXC5xPNg= 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 [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 5786E385780D for ; Wed, 2 Dec 2020 11:30:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5786E385780D 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-392-YNTRZXprMS-ZFnKH3DZATg-1; Wed, 02 Dec 2020 06:30:06 -0500 X-MC-Unique: YNTRZXprMS-ZFnKH3DZATg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C6020100F345 for ; Wed, 2 Dec 2020 11:30:05 +0000 (UTC) Received: from oldenburg2.str.redhat.com (ovpn-112-44.ams2.redhat.com [10.36.112.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1A68C60BFA for ; Wed, 2 Dec 2020 11:30:04 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH v2 1/2] Replace __libc_multiple_libcs with __libc_initial flag Message-Id: Date: Wed, 02 Dec 2020 12:30:03 +0100 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.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.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_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-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Change sbrk to fail for !__libc_initial (in the generic implementation). As a result, sbrk is (relatively) safe to use for the __libc_initial case (from the main libc). It is therefore no longer necessary to avoid using it in that case (or updating the brk cache), and the __libc_initial flag does not need to be updated as part of dlmopen or static dlopen. As before, direct brk system calls on Linux may lead to memory corruption. Reviewed-by: Adhemerval Zanella --- v2: Switch to a flag with just two states, simplifying the code. Add sbrk blocking for inner libcs. brk can't be changed yet due to the pending refactoring. csu/init-first.c | 10 +++------ csu/libc-start.c | 13 +++++------ elf/dl-open.c | 6 ----- elf/dl-sysdep.c | 2 -- elf/libc_early_init.c | 9 ++++++++ include/libc-internal.h | 7 +++++- misc/sbrk.c | 34 ++++++++++++++++++++--------- sysdeps/mach/hurd/dl-sysdep.c | 2 -- sysdeps/mach/hurd/i386/init-first.c | 10 +++++---- 9 files changed, 53 insertions(+), 40 deletions(-) diff --git a/csu/init-first.c b/csu/init-first.c index 47aaacdbd0..2115215668 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -28,10 +28,6 @@ #include -/* Set nonzero if we have to be prepared for more than one libc being - used in the process. Safe assumption if initializer never runs. */ -int __libc_multiple_libcs attribute_hidden = 1; - /* Remember the command line argument and enviroment contents for later calls of initializers for dynamic libraries. */ int __libc_argc attribute_hidden; @@ -50,16 +46,16 @@ _init_first (int argc, char **argv, char **envp) { #endif - __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; - /* Make sure we don't initialize twice. */ - if (!__libc_multiple_libcs) +#ifdef SHARED + if (__libc_initial) { /* Set the FPU control word to the proper default value if the kernel would use a different value. */ if (__fpu_control != GLRO(dl_fpu_control)) __setfpucw (__fpu_control); } +#endif /* Save the command-line arguments. */ __libc_argc = argc; diff --git a/csu/libc-start.c b/csu/libc-start.c index 2d4d2ed1f9..d330812c2d 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -141,8 +141,6 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), /* Result of the 'main' function. */ int result; - __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; - #ifndef SHARED _dl_relocate_static_pie (); @@ -213,12 +211,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), # endif # ifdef DL_SYSDEP_OSCHECK - if (!__libc_multiple_libcs) - { - /* This needs to run to initiliaze _dl_osversion before TLS - setup might check it. */ - DL_SYSDEP_OSCHECK (__libc_fatal); - } + { + /* This needs to run to initiliaze _dl_osversion before TLS + setup might check it. */ + DL_SYSDEP_OSCHECK (__libc_fatal); + } # endif /* Initialize libpthread if linked in. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index 8769e47051..6710ea04cd 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -787,12 +787,6 @@ dl_open_worker (void *a) if (mode & RTLD_GLOBAL) add_to_global_update (new); -#ifndef SHARED - /* We must be the static _dl_open in libc.a. A static program that - has loaded a dynamic object now has competition. */ - __libc_multiple_libcs = 1; -#endif - /* Let the user know about the opencount. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c index 854570821c..6cc4a76560 100644 --- a/elf/dl-sysdep.c +++ b/elf/dl-sysdep.c @@ -58,8 +58,6 @@ ElfW(Addr) _dl_base_addr; #endif int __libc_enable_secure attribute_relro = 0; rtld_hidden_data_def (__libc_enable_secure) -int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion - of init-first. */ /* This variable contains the lowest stack address ever used. */ void *__libc_stack_end attribute_relro = NULL; rtld_hidden_data_def(__libc_stack_end) diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c index 725ab2f811..28c6adca10 100644 --- a/elf/libc_early_init.c +++ b/elf/libc_early_init.c @@ -18,8 +18,13 @@ #include #include +#include #include +#ifdef SHARED +_Bool __libc_initial; +#endif + void __libc_early_init (_Bool initial) { @@ -28,4 +33,8 @@ __libc_early_init (_Bool initial) /* Only the outer namespace is marked as single-threaded. */ __libc_single_threaded = initial; + +#ifdef SHARED + __libc_initial = initial; +#endif } diff --git a/include/libc-internal.h b/include/libc-internal.h index 915613c030..c1e74056ac 100644 --- a/include/libc-internal.h +++ b/include/libc-internal.h @@ -47,6 +47,11 @@ extern void __init_misc (int, char **, char **) attribute_hidden; extern __typeof (__profile_frequency) __profile_frequency attribute_hidden; # endif -extern int __libc_multiple_libcs attribute_hidden; +#ifdef SHARED +/* True if this libc belongs to the initially loaded program (i.e., it + is not for an audit module, not loaded via dlmopen, and not loaded + via static dlopen either). */ +extern _Bool __libc_initial attribute_hidden; +#endif #endif /* _LIBC_INTERNAL */ diff --git a/misc/sbrk.c b/misc/sbrk.c index ba3322fba6..a6929d736d 100644 --- a/misc/sbrk.c +++ b/misc/sbrk.c @@ -16,9 +16,10 @@ . */ #include +#include +#include #include #include -#include /* Defined in brk.c. */ extern void *__curbrk; @@ -30,21 +31,34 @@ extern int __brk (void *addr); void * __sbrk (intptr_t increment) { - void *oldbrk; - - /* If this is not part of the dynamic library or the library is used - via dynamic loading in a statically linked program update - __curbrk from the kernel's brk value. That way two separate - instances of __brk and __sbrk can share the heap, returning - interleaved pieces of it. */ - if (__curbrk == NULL || __libc_multiple_libcs) + /* Controls whether __brk (0) is called to read the brk value from + the kernel. */ + bool update_brk = __curbrk == NULL; + +#if defined (SHARED) && ! IS_IN (rtld) + if (!__libc_initial) + { + if (increment != 0) + { + /* Do not allow changing the brk from an inner libc because + it cannot be synchronized with the outer libc's brk. */ + __set_errno (ENOMEM); + return (void *) -1; + } + /* Querying the kernel's brk value from an inner namespace is + fine. */ + update_brk = true; + } +#endif + + if (update_brk) if (__brk (0) < 0) /* Initialize the break. */ return (void *) -1; if (increment == 0) return __curbrk; - oldbrk = __curbrk; + void *oldbrk = __curbrk; if (increment > 0 ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk) : ((uintptr_t) oldbrk < (uintptr_t) -increment)) diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 370495710e..a5169d85e7 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -57,8 +57,6 @@ extern char **_environ; int __libc_enable_secure = 0; rtld_hidden_data_def (__libc_enable_secure) -int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion - of init-first. */ /* This variable contains the lowest stack address ever used. */ void *__libc_stack_end = NULL; rtld_hidden_data_def(__libc_stack_end) diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index 1827479f86..cbbc12204a 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -30,6 +30,7 @@ #include #include #include +#include extern void __mach_init (void); extern void __init_misc (int, char **, char **); @@ -40,7 +41,6 @@ unsigned long int __hurd_threadvar_stack_mask; #ifndef SHARED int __libc_enable_secure; #endif -int __libc_multiple_libcs attribute_hidden = 1; extern int __libc_argc attribute_hidden; extern char **__libc_argv attribute_hidden; @@ -56,13 +56,12 @@ DEFINE_HOOK (_hurd_preinit_hook, (void)); static void posixland_init (int argc, char **argv, char **envp) { - __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; - /* Now we have relocations etc. we can start signals etc. */ _hurd_libc_proc_init (argv); +#ifdef SHARED /* Make sure we don't initialize twice. */ - if (!__libc_multiple_libcs) + if (__libc_initial) { /* Set the FPU control word to the proper default value. */ __setfpucw (__fpu_control); @@ -72,6 +71,9 @@ posixland_init (int argc, char **argv, char **envp) /* Initialize data structures so the additional libc can do RPCs. */ __mach_init (); } +#else /* !SHARED */ + __setfpucw (__fpu_control); +#endif /* Save the command-line arguments. */ __libc_argc = argc; From patchwork Wed Dec 2 11:30:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 1409657 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=qyyx1lch; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CmGx35k68z9sVw for ; Wed, 2 Dec 2020 22:30:31 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DF517395B454; Wed, 2 Dec 2020 11:30:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DF517395B454 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1606908627; bh=OBdKndrdtxAFqLaAERd6e/upAXHsfXTU5+oCRAYUtpQ=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=qyyx1lchT+zKduTsDnBXme9KWm2UMblK6pLLp6oa/DgTHsVyCBs7WfcPSkmnNhSSe OmVyt6L2gcCh/hMbmvKPYeNKpcw0nLGkdnNAYetBHEmTZGijb0ncORg1td06RvFVVD jq4OdaB8/jkgKW6YXr5T7QvV0Dol9DB7IaYsEhm4= 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 [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 790853857806 for ; Wed, 2 Dec 2020 11:30:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 790853857806 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-348-6-HMrG3VNNmEk7aFtfuL8w-1; Wed, 02 Dec 2020 06:30:23 -0500 X-MC-Unique: 6-HMrG3VNNmEk7aFtfuL8w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C48501012E8D for ; Wed, 2 Dec 2020 11:30:22 +0000 (UTC) Received: from oldenburg2.str.redhat.com (ovpn-112-44.ams2.redhat.com [10.36.112.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 46AED5C1BD for ; Wed, 2 Dec 2020 11:30:22 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH v2 2/2] malloc: Use __libc_initial to detect an inner libc In-Reply-To: References: Message-Id: Date: Wed, 02 Dec 2020 12:30:20 +0100 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.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.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_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-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" The secondary/non-primary/inner libc (loaded via dlmopen, LD_AUDIT, static dlopen) must not use sbrk to allocate member because that would interfere with allocations in the outer libc. On Linux, this does not matter because sbrk itself was changed to fail in secondary libcs. _dl_addr occasionally shows up in profiles, but had to be used before because __libc_multiple_libs was unreliable. So this change achieves a slight reduction in startup time. Reviewed-by: Adhemerval Zanella --- v2: Adjust to the first patch. malloc/arena.c | 13 +++++-------- malloc/malloc.c | 2 ++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/malloc/arena.c b/malloc/arena.c index 202daf15b0..3c9c0ecd86 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -294,14 +294,11 @@ ptmalloc_init (void) __malloc_initialized = 0; #ifdef SHARED - /* In case this libc copy is in a non-default namespace, never use brk. - Likewise if dlopened from statically linked program. */ - Dl_info di; - struct link_map *l; - - if (_dl_open_hook != NULL - || (_dl_addr (ptmalloc_init, &di, &l, NULL) != 0 - && l->l_ns != LM_ID_BASE)) + /* In case this libc copy is in a non-default namespace, never use + brk. Likewise if dlopened from statically linked program. The + generic sbrk implementation also enforces this, but it is not + used on Hurd. */ + if (!__libc_initial) __morecore = __failing_morecore; #endif diff --git a/malloc/malloc.c b/malloc/malloc.c index 5b87bdb081..0834e4181a 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -247,6 +247,8 @@ /* For SINGLE_THREAD_P. */ #include +#include + /* Debugging: