From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS17314 8.43.84.0/22 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 dcvr.yhbt.net (Postfix) with ESMTPS id 752C81F9E0 for ; Wed, 29 Apr 2020 13:30:23 +0000 (UTC) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B721A3957052; Wed, 29 Apr 2020 13:30:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B721A3957052 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1588167021; bh=4FecjvQy0yLyGh5xzQvJ5WJ8za1v9CXLeBUm3eKqPRQ=; h=Subject:To:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=wJp3ijYEbPmQVgxauOH3kNNQVG09oEwv1KP5Zv3qRWzGuvbx/COVhGUiSvofYjJVk Y0mZXrOOBmPJ1FJ+cb+p84+fx/cigpz6pTc95sWUNx6xWhZQxi6LHronaiv2aQsGTa jftw/tw9g6MsBwbWbLLFTUmt7PKeVZvUOKiTbbww= Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by sourceware.org (Postfix) with ESMTP id E2C4A3893665 for ; Wed, 29 Apr 2020 13:30:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E2C4A3893665 Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-402-6OjRV6ETMh-0mMJ4Qd9R5A-1; Wed, 29 Apr 2020 09:30:13 -0400 X-MC-Unique: 6OjRV6ETMh-0mMJ4Qd9R5A-1 Received: by mail-qt1-f199.google.com with SMTP id f56so2662355qte.18 for ; Wed, 29 Apr 2020 06:30:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:organization :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=4FecjvQy0yLyGh5xzQvJ5WJ8za1v9CXLeBUm3eKqPRQ=; b=s0EoAhrkiFKMyHykwjOXcGTwUE7dQBVU5Idh0E9cUGU21S0UftfRpx+GF/5Ly61Y9/ 3ktJl4Bs79Lo8ufdMXPyY0KpHWIWXguqW+5ucnheasYjt25EefaDhcShkMKb6LrXGcvZ vORWRsvpEuS+EH5cANCpGt6PB/B81ne5hMDciVM3vfAQ0TUKMzzm82Yks+cM+kqjhPpJ 8kQ8sdPFgjXHw61IKhY3zkslegu2jUdNrDCTAlkvKRZnFOM2meVBGUaPeMNGLyvmUxeC SXzdid9RXXgnnHT0x2k4NbAHgfz7i6q+wfTbm3Ukm4LTytyz4HFhNBt4Q82obNZGr/a+ qZfA== X-Gm-Message-State: AGi0PuYiSSf20LbHj336xclc6DERMXiWj62w8Q2TyAE3sWznhqTzb0JB ZImbizHDO5Pfs4rg8Uv56BOnAR00U2tPHD3BLgf65SZkJyAEIK+PzZ0AdnOk5hcYYTJ+WoZPkLW Y6menjw6O2EYv3FN42po1 X-Received: by 2002:ac8:3713:: with SMTP id o19mr32821760qtb.371.1588167011946; Wed, 29 Apr 2020 06:30:11 -0700 (PDT) X-Google-Smtp-Source: APiQypK1ddFdvrIwYJNOXxQnfgkEmvCtfkCCd8EUX/46huZImgU/UgEhu8xboSUruquiI6gx5RKXaw== X-Received: by 2002:ac8:3713:: with SMTP id o19mr32821727qtb.371.1588167011502; Wed, 29 Apr 2020 06:30:11 -0700 (PDT) Received: from [192.168.1.4] (198-84-170-103.cpe.teksavvy.com. [198.84.170.103]) by smtp.gmail.com with ESMTPSA id t1sm132618qtd.65.2020.04.29.06.30.10 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Apr 2020 06:30:10 -0700 (PDT) Subject: Re: [PATCH] elf: Add initial flag argument to __libc_early_init To: Florian Weimer , libc-alpha@sourceware.org References: <87a72xxg86.fsf@mid.deneb.enyo.de> Organization: Red Hat Message-ID: Date: Wed, 29 Apr 2020 09:30:09 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: <87a72xxg86.fsf@mid.deneb.enyo.de> Content-Language: en-US X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit 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: , From: Carlos O'Donell via Libc-alpha Reply-To: Carlos O'Donell Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" On 4/27/20 8:31 AM, Florian Weimer wrote: > The rseq initialization should happen only for the libc in the base > namespace (in the dynamic case) or the statically linked libc. The > __libc_multiple_libcs flag does not quite cover this case at present, > so this commit introduces a flag argument to __libc_early_init, > indicating whether the libc being libc is the primary one (of the main > program). Yes, __libc_multiple_libcs tells you if there are multiple libcs present, but doesn't tell you which is the first, and which should be initialized, so you have to pipe that down from early startup which knows which is the first. In the case we extend this following Vivek's code to add proxy object for libc into subsequent namespaces it will continue to work because the base libc is initialized and then exposed into the later namespaces via a linkmap that is a proxy. We might have to adjust this a bit because libc_map->l_ns == LM_ID_BASE will be true in all namespaces because the libc_map will be a proxy for the runtime into all namespaces to facilitate coordination of TLS and other parameters (in the case where dlmopen supports isolation *beyond* the core runtime). It should be straight forward though, since Vivek added a "is this a proxy" parameter to the link map which we can check. OK for master. Reviewed-by: Carlos O'Donell > Tested on i686-linux-gnu and x86_64-linux-gnu (although the new flag > is currently not used). > > ----- > csu/libc-start.c | 3 ++- > elf/dl-call-libc-early-init.c | 4 ++-- > elf/dl-open.c | 17 +++++++++++++++-- > elf/libc-early-init.h | 11 +++++++---- > elf/libc_early_init.c | 2 +- > elf/rtld.c | 6 ++++-- > 6 files changed, 31 insertions(+), 12 deletions(-) > > diff --git a/csu/libc-start.c b/csu/libc-start.c > index ccc743c9d1..4005caf84a 100644 > --- a/csu/libc-start.c > +++ b/csu/libc-start.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > > #include > > @@ -241,7 +242,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), > #ifndef SHARED > /* Perform early initialization. In the shared case, this function > is called from the dynamic loader as early as possible. */ > - __libc_early_init (); > + __libc_early_init (true); OK, in LIBC_START_MAIN we are the first libc. > > /* Call the initializer of the libc. This is only needed here if we > are compiling for the static library in which case we haven't > diff --git a/elf/dl-call-libc-early-init.c b/elf/dl-call-libc-early-init.c > index 41e9ad9aad..9a84680a1c 100644 > --- a/elf/dl-call-libc-early-init.c > +++ b/elf/dl-call-libc-early-init.c > @@ -23,7 +23,7 @@ > #include > > void > -_dl_call_libc_early_init (struct link_map *libc_map) > +_dl_call_libc_early_init (struct link_map *libc_map, _Bool initial) > { > /* There is nothing to do if we did not actually load libc.so. */ > if (libc_map == NULL) > @@ -37,5 +37,5 @@ _dl_call_libc_early_init (struct link_map *libc_map) > assert (sym != NULL); > __typeof (__libc_early_init) *early_init > = DL_SYMBOL_ADDRESS (libc_map, sym); > - early_init (); > + early_init (initial); OK. Pass parameter to early_init() function which we looked up in libc. > } > diff --git a/elf/dl-open.c b/elf/dl-open.c > index ac7ab495e4..7bf1144e93 100644 > --- a/elf/dl-open.c > +++ b/elf/dl-open.c > @@ -748,9 +748,22 @@ dl_open_worker (void *a) > LIBC_PROBE (reloc_complete, 3, args->nsid, r, new); > > /* If libc.so was not there before, attempt to call its early > - initialization routine. */ > + initialization routine. Indicate to the initialization routine > + whether thie libc being initialized is the one in the base > + namespace. */ > if (!args->libc_already_loaded) > - _dl_call_libc_early_init (GL(dl_ns)[args->nsid].libc_map); > + { > + struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map; > +#ifdef SHARED > + bool initial = libc_map->l_ns == LM_ID_BASE; OK. In the shared case we must be in the base namespace, as that insures that this is the first loaded libc. > +#else > + /* In the static case, there is only one namespace, but it > + contains a secondary libc (the primary libc is statically > + linked). */ > + bool initial = false; OK. In the static case it's a secondary libc. > +#endif > + _dl_call_libc_early_init (libc_map, initial); > + } > > #ifndef SHARED > DL_STATIC_INIT (new); > diff --git a/elf/libc-early-init.h b/elf/libc-early-init.h > index 5185fa8895..8f7836dcea 100644 > --- a/elf/libc-early-init.h > +++ b/elf/libc-early-init.h > @@ -22,14 +22,17 @@ > struct link_map; > > /* If LIBC_MAP is not NULL, look up the __libc_early_init symbol in it > - and call this function. */ > -void _dl_call_libc_early_init (struct link_map *libc_map) attribute_hidden; > + and call this function, with INITIAL as the argument. */ > +void _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial) > + attribute_hidden; OK. > > /* In the shared case, this function is defined in libc.so and invoked > from ld.so (or on the fist static dlopen) after complete relocation > of a new loaded libc.so, but before user-defined ELF constructors > run. In the static case, this function is called directly from the > - startup code. */ > -void __libc_early_init (void); > + startup code. If INITIAL is true, the libc being initialized is > + the libc for the main program. INITIAL is false for libcs loaded > + for audit modules, dlmopen, and static dlopen. */ > +void __libc_early_init (_Bool initial); OK. > > #endif /* _LIBC_EARLY_INIT_H */ > diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c > index 7f4ca332b8..e6c64fb526 100644 > --- a/elf/libc_early_init.c > +++ b/elf/libc_early_init.c > @@ -20,7 +20,7 @@ > #include > > void > -__libc_early_init (void) > +__libc_early_init (_Bool initial) OK. Add bool to definition. > { > /* Initialize ctype data. */ > __ctype_init (); > diff --git a/elf/rtld.c b/elf/rtld.c > index 0016db86a7..5ccc3c2dbb 100644 > --- a/elf/rtld.c > +++ b/elf/rtld.c > @@ -2373,8 +2373,10 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); > rtld_timer_accum (&relocate_time, start); > } > > - /* Relocation is complete. Perform early libc initialization. */ > - _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map); > + /* Relocation is complete. Perform early libc initialization. This > + is the initial libc, even if audit modules have been loaded with > + other libcs. */ > + _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map, true); OK. This is dl_main so this is always the initial libc initialization point *if* we entered through the dynamic loader. > > /* Do any necessary cleanups for the startup OS interface code. > We do these now so that no calls are made after rtld re-relocation > -- Cheers, Carlos.