From patchwork Fri Feb 11 16:29:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 51050 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 DDE223858013 for ; Fri, 11 Feb 2022 16:30:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DDE223858013 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644597024; bh=Nzjg7y2QtctqywVKOijytPX+jm2/QDQsRXRnFJlLwlc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=QElQPKmjh17dmaEGXxHUXiee1WcloTtIdnr3MQELWvvFLGksywsT2P63OULhfmbve khnGrcq6zVCM4FEMysbyNYiDOyHPoo+cWGLET2ry0gFClyDDfpvMhraf0pNzetH7sq R7GyBnn7oJBs2ohYh5ce0AqZHS0FYYLjmmhZU4aY= 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 ESMTPS id 2A2FB3858D1E for ; Fri, 11 Feb 2022 16:30:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A2FB3858D1E Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-16-WL_9w6IJMgmqcjJ2BIgrFA-1; Fri, 11 Feb 2022 11:30:00 -0500 X-MC-Unique: WL_9w6IJMgmqcjJ2BIgrFA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A710C760C1 for ; Fri, 11 Feb 2022 16:29:59 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.193.205]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 20F6A2DE61 for ; Fri, 11 Feb 2022 16:29:57 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH COMMITTED] Revert "Linux: Consolidate auxiliary vector parsing" Date: Fri, 11 Feb 2022 17:29:56 +0100 Message-ID: <878ruhtlh7.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 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_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This reverts commit 8c8510ab2790039e58995ef3a22309582413d3ff. The revert is not perfect because the commit included a bug fix for _dl_sysdep_start with an empty argv, introduced in commit 2d47fa68628e831a692cba8fc9050cef435afc5e ("Linux: Remove DL_FIND_ARG_COMPONENTS"), and this bug fix is kept. The revert is necessary because the reverted commit introduced an early memset call on aarch64, which leads to crash due to lack of TCB initialization. --- elf/dl-support.c | 80 +++++++++++++++++++- sysdeps/unix/sysv/linux/alpha/dl-auxv.h | 18 +++-- sysdeps/unix/sysv/linux/dl-parse_auxv.h | 61 --------------- sysdeps/unix/sysv/linux/dl-sysdep.c | 109 +++++++++++++++++++-------- sysdeps/unix/sysv/linux/powerpc/dl-auxv.h | 14 +++- sysdeps/unix/sysv/linux/powerpc/dl-support.c | 4 - 6 files changed, 180 insertions(+), 106 deletions(-) diff --git a/elf/dl-support.c b/elf/dl-support.c index 1977a2be76..6d2c4baf81 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -240,21 +240,93 @@ __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock) #ifdef HAVE_AUX_VECTOR -#include - int _dl_clktck; void _dl_aux_init (ElfW(auxv_t) *av) { + int seen = 0; + uid_t uid = 0; + gid_t gid = 0; + #ifdef NEED_DL_SYSINFO /* NB: Avoid RELATIVE relocation in static PIE. */ GL(dl_sysinfo) = DL_SYSINFO_DEFAULT; #endif _dl_auxv = av; - dl_parse_auxv_t auxv_values = { 0, }; - _dl_parse_auxv (av, auxv_values); + for (; av->a_type != AT_NULL; ++av) + switch (av->a_type) + { + case AT_PAGESZ: + if (av->a_un.a_val != 0) + GLRO(dl_pagesize) = av->a_un.a_val; + break; + case AT_CLKTCK: + GLRO(dl_clktck) = av->a_un.a_val; + break; + case AT_PHDR: + GL(dl_phdr) = (const void *) av->a_un.a_val; + break; + case AT_PHNUM: + GL(dl_phnum) = av->a_un.a_val; + break; + case AT_PLATFORM: + GLRO(dl_platform) = (void *) av->a_un.a_val; + break; + case AT_HWCAP: + GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; + break; + case AT_HWCAP2: + GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; + break; + case AT_FPUCW: + GLRO(dl_fpu_control) = av->a_un.a_val; + break; +#ifdef NEED_DL_SYSINFO + case AT_SYSINFO: + GL(dl_sysinfo) = av->a_un.a_val; + break; +#endif +#ifdef NEED_DL_SYSINFO_DSO + case AT_SYSINFO_EHDR: + GL(dl_sysinfo_dso) = (void *) av->a_un.a_val; + break; +#endif + case AT_UID: + uid ^= av->a_un.a_val; + seen |= 1; + break; + case AT_EUID: + uid ^= av->a_un.a_val; + seen |= 2; + break; + case AT_GID: + gid ^= av->a_un.a_val; + seen |= 4; + break; + case AT_EGID: + gid ^= av->a_un.a_val; + seen |= 8; + break; + case AT_SECURE: + seen = -1; + __libc_enable_secure = av->a_un.a_val; + __libc_enable_secure_decided = 1; + break; + case AT_RANDOM: + _dl_random = (void *) av->a_un.a_val; + break; + case AT_MINSIGSTKSZ: + _dl_minsigstacksize = av->a_un.a_val; + break; + DL_PLATFORM_AUXV + } + if (seen == 0xf) + { + __libc_enable_secure = uid != 0 || gid != 0; + __libc_enable_secure_decided = 1; + } } #endif diff --git a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h index fcec743239..81d90da095 100644 --- a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h +++ b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h @@ -20,8 +20,16 @@ extern long __libc_alpha_cache_shape[4]; -#define DL_PLATFORM_AUXV \ - __libc_alpha_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \ - __libc_alpha_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \ - __libc_alpha_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE]; \ - __libc_alpha_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE]; +#define DL_PLATFORM_AUXV \ + case AT_L1I_CACHESHAPE: \ + __libc_alpha_cache_shape[0] = av->a_un.a_val; \ + break; \ + case AT_L1D_CACHESHAPE: \ + __libc_alpha_cache_shape[1] = av->a_un.a_val; \ + break; \ + case AT_L2_CACHESHAPE: \ + __libc_alpha_cache_shape[2] = av->a_un.a_val; \ + break; \ + case AT_L3_CACHESHAPE: \ + __libc_alpha_cache_shape[3] = av->a_un.a_val; \ + break; diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h deleted file mode 100644 index b3d82f6994..0000000000 --- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Parse the Linux auxiliary vector. - Copyright (C) 1995-2022 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 -#include -#include -#include - -typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; - -/* Copy the auxiliary vector into AUX_VALUES and set up GLRO - variables. */ -static inline -void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) -{ - auxv_values[AT_ENTRY] = (ElfW(Addr)) ENTRY_POINT; - auxv_values[AT_PAGESZ] = EXEC_PAGESIZE; - auxv_values[AT_FPUCW] = _FPU_DEFAULT; - - /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ - _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), - "CONSTANT_MINSIGSTKSZ is constant"); - auxv_values[AT_MINSIGSTKSZ] = CONSTANT_MINSIGSTKSZ; - - for (; av->a_type != AT_NULL; av++) - if (av->a_type <= AT_MINSIGSTKSZ) - auxv_values[av->a_type] = av->a_un.a_val; - - GLRO(dl_pagesize) = auxv_values[AT_PAGESZ]; - __libc_enable_secure = auxv_values[AT_SECURE]; - GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM]; - GLRO(dl_hwcap) = auxv_values[AT_HWCAP]; - GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2]; - GLRO(dl_clktck) = auxv_values[AT_CLKTCK]; - GLRO(dl_fpu_control) = auxv_values[AT_FPUCW]; - _dl_random = (void *) auxv_values[AT_RANDOM]; - GLRO(dl_minsigstacksize) = auxv_values[AT_MINSIGSTKSZ]; - GLRO(dl_sysinfo_dso) = (void *) auxv_values[AT_SYSINFO_EHDR]; -#ifdef NEED_DL_SYSINFO - if (GLRO(dl_sysinfo_dso) != NULL) - GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; -#endif - - DL_PLATFORM_AUXV -} diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c index 71cf1968b5..5e71704fcf 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c @@ -21,12 +21,13 @@ #include #include #include -#include #include #include #include +#include #include #include +#include #include #include #include @@ -62,20 +63,20 @@ void *_dl_random attribute_relro = NULL; # define DL_STACK_END(cookie) ((void *) (cookie)) #endif -/* Arguments passed to dl_main. */ -struct dl_main_arguments +ElfW(Addr) +_dl_sysdep_start (void **start_argptr, + void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, + ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) { - const ElfW(Phdr) *phdr; - ElfW(Word) phnum; + const ElfW(Phdr) *phdr = NULL; + ElfW(Word) phnum = 0; ElfW(Addr) user_entry; -}; + ElfW(auxv_t) *av; +#ifdef NEED_DL_SYSINFO + uintptr_t new_sysinfo = 0; +#endif -/* Separate function, so that dl_main can be called without the large - array on the stack. */ -static void -_dl_sysdep_parse_arguments (void **start_argptr, - struct dl_main_arguments *args) -{ + __libc_stack_end = DL_STACK_END (start_argptr); _dl_argc = (intptr_t) *start_argptr; _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation. */ _environ = _dl_argv + _dl_argc + 1; @@ -87,26 +88,75 @@ _dl_sysdep_parse_arguments (void **start_argptr, break; } - dl_parse_auxv_t auxv_values = { 0, }; - _dl_parse_auxv (GLRO(dl_auxv), auxv_values); + user_entry = (ElfW(Addr)) ENTRY_POINT; + GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */ - args->phdr = (const ElfW(Phdr) *) auxv_values[AT_PHDR]; - args->phnum = auxv_values[AT_PHNUM]; - args->user_entry = auxv_values[AT_ENTRY]; -} + /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */ + _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), + "CONSTANT_MINSIGSTKSZ is constant"); + GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; -ElfW(Addr) -_dl_sysdep_start (void **start_argptr, - void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, - ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) -{ - __libc_stack_end = DL_STACK_END (start_argptr); - - struct dl_main_arguments dl_main_args; - _dl_sysdep_parse_arguments (start_argptr, &dl_main_args); + for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++) + switch (av->a_type) + { + case AT_PHDR: + phdr = (void *) av->a_un.a_val; + break; + case AT_PHNUM: + phnum = av->a_un.a_val; + break; + case AT_PAGESZ: + GLRO(dl_pagesize) = av->a_un.a_val; + break; + case AT_ENTRY: + user_entry = av->a_un.a_val; + break; + case AT_SECURE: + __libc_enable_secure = av->a_un.a_val; + break; + case AT_PLATFORM: + GLRO(dl_platform) = (void *) av->a_un.a_val; + break; + case AT_HWCAP: + GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; + break; + case AT_HWCAP2: + GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; + break; + case AT_CLKTCK: + GLRO(dl_clktck) = av->a_un.a_val; + break; + case AT_FPUCW: + GLRO(dl_fpu_control) = av->a_un.a_val; + break; +#ifdef NEED_DL_SYSINFO + case AT_SYSINFO: + new_sysinfo = av->a_un.a_val; + break; +#endif + case AT_SYSINFO_EHDR: + GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val; + break; + case AT_RANDOM: + _dl_random = (void *) av->a_un.a_val; + break; + case AT_MINSIGSTKSZ: + GLRO(dl_minsigstacksize) = av->a_un.a_val; + break; + DL_PLATFORM_AUXV + } dl_hwcap_check (); +#ifdef NEED_DL_SYSINFO + if (new_sysinfo != 0) + { + /* Only set the sysinfo value if we also have the vsyscall DSO. */ + if (GLRO(dl_sysinfo_dso) != 0) + GLRO(dl_sysinfo) = new_sysinfo; + } +#endif + __tunables_init (_environ); /* Initialize DSO sorting algorithm after tunables. */ @@ -137,9 +187,8 @@ _dl_sysdep_start (void **start_argptr, if (__builtin_expect (__libc_enable_secure, 0)) __libc_check_standard_fds (); - (*dl_main) (dl_main_args.phdr, dl_main_args.phnum, - &dl_main_args.user_entry, GLRO(dl_auxv)); - return dl_main_args.user_entry; + (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv)); + return user_entry; } void diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h index ce2281cf11..594371940a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h +++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h @@ -16,5 +16,15 @@ License along with the GNU C Library; if not, see . */ -#define DL_PLATFORM_AUXV \ - GLRO(dl_cache_line_size) = auxv_values[AT_DCACHEBSIZE]; +#include + +#if IS_IN (libc) && !defined SHARED +int GLRO(dl_cache_line_size); +#endif + +/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it + to dl_cache_line_size. */ +#define DL_PLATFORM_AUXV \ + case AT_DCACHEBSIZE: \ + GLRO(dl_cache_line_size) = av->a_un.a_val; \ + break; diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-support.c b/sysdeps/unix/sysv/linux/powerpc/dl-support.c deleted file mode 100644 index abe68a7049..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/dl-support.c +++ /dev/null @@ -1,4 +0,0 @@ -#include - -/* Populated from the auxiliary vector. */ -int _dl_cache_line_size;