From patchwork Fri Nov 13 16:14: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: 41045 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 E3E95384A01C; Fri, 13 Nov 2020 16:14:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E3E95384A01C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1605284056; bh=8I15Xj/wbZEBophW5o/5+lnxtC5eUSHic+rkQHglLxI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=T4nD2XkZ7FnnWsU4jWNM8mkankp0BbvBtEXBW26Dcj518dMe7yEZVHotsvFlU2qrN e0LvfN5/KXHk1dB2XLL4+sToqALqLDInykFnL9GaVQ9jtLopIZ0Gfjksi9g5uPWdcI DAK9h4FGzm3VTYwqyZwkx8vyE91qDGsXt9IH79UQ= 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 21A983858004 for ; Fri, 13 Nov 2020 16:14:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 21A983858004 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-144-F6d8nPRnPsaV5d1AVQEk2w-1; Fri, 13 Nov 2020 11:14:06 -0500 X-MC-Unique: F6d8nPRnPsaV5d1AVQEk2w-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 7E38F1009E44 for ; Fri, 13 Nov 2020 16:14:05 +0000 (UTC) Received: from oldenburg2.str.redhat.com (ovpn-113-222.ams2.redhat.com [10.36.113.222]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B9E4F60C84 for ; Fri, 13 Nov 2020 16:14:04 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH 1/2] Replace __libc_multiple_libcs with tri-state __libc_type Message-Id: <7e89ec4dee33dd4eef6986dd0e790a9500c430b6.1605283657.git.fweimer@redhat.com> Date: Fri, 13 Nov 2020 17:14: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.2 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_H5, 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 three states are (1) initial libc without any other libcs loaded (yet), (2) initial with other libcs loaded, and (3) secondary libc (audit module, inner libc after dlmopen, inner libc as the result of static dlopen). The three states are required because we want to use sbrk for the malloc in the primary libc, whether or not secondary libcs have been loaded. ptmalloc_init currently uses _dl_addr to detect inner namespaces because __libc_multiple_libcs is not set up correctly for audit modules (because _dl_starting_up is not used on Linux). --- csu/init-first.c | 8 +------- csu/libc-start.c | 4 +--- dlfcn/dlmopen.c | 6 ++++++ elf/Versions | 3 +++ elf/dl-open.c | 2 +- elf/dl-sysdep.c | 2 -- elf/libc_early_init.c | 22 ++++++++++++++++++++++ include/libc-internal.h | 18 +++++++++++++++++- misc/sbrk.c | 11 +++++++++-- sysdeps/mach/hurd/dl-sysdep.c | 2 -- sysdeps/mach/hurd/i386/init-first.c | 5 +---- 11 files changed, 61 insertions(+), 22 deletions(-) diff --git a/csu/init-first.c b/csu/init-first.c index 47aaacdbd0..28fa66ad54 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,10 +46,8 @@ _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) + if (__libc_type != libc_type_secondary) { /* Set the FPU control word to the proper default value if the kernel would use a different value. */ diff --git a/csu/libc-start.c b/csu/libc-start.c index 2d4d2ed1f9..7e0c4ce610 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,7 +211,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), # endif # ifdef DL_SYSDEP_OSCHECK - if (!__libc_multiple_libcs) + if (__libc_type != libc_type_secondary) { /* This needs to run to initiliaze _dl_osversion before TLS setup might check it. */ diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c index 1396c818ac..c880c13443 100644 --- a/dlfcn/dlmopen.c +++ b/dlfcn/dlmopen.c @@ -22,6 +22,7 @@ #include #include #include +#include #if !defined SHARED && IS_IN (libdl) @@ -79,6 +80,11 @@ void * __dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL) { # ifdef SHARED + /* Advertise that we may have multiple libc from now on. Do not + overwrite a libc_type_secondary value. */ + if (__libc_type == libc_type_initial_only) + __libc_type = libc_type_initial; + if (!rtld_active ()) return _dlfcn_hook->dlmopen (nsid, file, mode, RETURN_ADDRESS (0)); # endif diff --git a/elf/Versions b/elf/Versions index be88c48e6d..39df728f0a 100644 --- a/elf/Versions +++ b/elf/Versions @@ -28,6 +28,9 @@ libc { __libc_dlclose; __libc_dlopen_mode; __libc_dlsym; __libc_dlvsym; __libc_early_init; + # Updated from libdl. + __libc_type; + # Internal error handling support. Interposes the functions in ld.so. _dl_signal_exception; _dl_catch_exception; _dl_signal_error; _dl_catch_error; diff --git a/elf/dl-open.c b/elf/dl-open.c index 8769e47051..7b7a9214b8 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -790,7 +790,7 @@ dl_open_worker (void *a) #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; + __libc_type = libc_type_initial; #endif /* Let the user know about the opencount. */ 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..fec5d6035e 100644 --- a/elf/libc_early_init.c +++ b/elf/libc_early_init.c @@ -17,9 +17,14 @@ . */ #include +#include #include +#include #include +char __libc_type __attribute__ ((nocommon)); +libc_hidden_def (__libc_type) + void __libc_early_init (_Bool initial) { @@ -28,4 +33,21 @@ __libc_early_init (_Bool initial) /* Only the outer namespace is marked as single-threaded. */ __libc_single_threaded = initial; + +#ifdef SHARED + if (initial) + { + if (GLRO (dl_naudit) == 0) + __libc_type = libc_type_initial_only; + else + /* If auditing is active, the initial libc is not the only + libc. */ + __libc_type = libc_type_initial; + } + else + __libc_type = libc_type_secondary; +#else + /* There is no auditing support for statically linked binaries. */ + __libc_type = libc_type_initial_only; +#endif } diff --git a/include/libc-internal.h b/include/libc-internal.h index 915613c030..7331ff2c51 100644 --- a/include/libc-internal.h +++ b/include/libc-internal.h @@ -47,6 +47,22 @@ 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; +enum + { + /* The running libc is the only libc in the process image. It can + transition to libc_type_initial via dlmopen or static + dlopen. */ + libc_type_initial_only, + + /* The running libc is the libc for the main program, but other + libcs may have been loaded. */ + libc_type_initial, + + /* The running libc is a secondary libc (loaded via dlmopen, to + support auditing, or for static dlopen). */ + libc_type_secondary, + }; +extern char __libc_type; +libc_hidden_proto (__libc_type) #endif /* _LIBC_INTERNAL */ diff --git a/misc/sbrk.c b/misc/sbrk.c index ba3322fba6..88840b426b 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; @@ -37,7 +38,13 @@ __sbrk (intptr_t increment) __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) +#if IS_IN (rtld) + bool update_curbrk = __curbrk == NULL; +#else + bool update_curbrk = (__curbrk == NULL + || __libc_type != libc_type_initial_only); +#endif + if (update_curbrk) if (__brk (0) < 0) /* Initialize the break. */ return (void *) -1; 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..8497089f7a 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -40,7 +40,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 +55,11 @@ 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); /* Make sure we don't initialize twice. */ - if (!__libc_multiple_libcs) + if (__libc_type != libc_type_secondary) { /* Set the FPU control word to the proper default value. */ __setfpucw (__fpu_control);