From patchwork Thu Jul 15 09:11:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 44370 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 AABCD3AAAC29 for ; Thu, 15 Jul 2021 09:31:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AABCD3AAAC29 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1626341508; bh=DErtfnPmkvD1KAmWfISO9UHWsWTZ7W/fXAI8S+YHPRg=; 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=ZOO/M0Jn38UbM7IoRyi6jrzzxZPbRAChaodCkuJfDaakn1tpKESLpkZoc+JlyUso7 MsC/u5M5raw+qf8LZiHcAFmmwBA6zLvXVYOavXrozbUZ7ogoVVbXEJxpK3+NM3W/1C Nay72RW563PsJeWSKzlEA/sXwx3YK+AAC73cf+Vw= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id C4A2D3AA9C1F for ; Thu, 15 Jul 2021 09:11:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C4A2D3AA9C1F 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-475-WCdypSE9MEayUWy9mcdwIg-1; Thu, 15 Jul 2021 05:11:07 -0400 X-MC-Unique: WCdypSE9MEayUWy9mcdwIg-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 347D9100B3AC for ; Thu, 15 Jul 2021 09:11:06 +0000 (UTC) Received: from oldenburg.str.redhat.com (ovpn-112-73.phx2.redhat.com [10.3.112.73]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 52F535C225 for ; Thu, 15 Jul 2021 09:11:05 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH 24/24] nss: Directly load nss_dns, without going through dlsym/dlopen In-Reply-To: References: X-From-Line: 1039263f503f5767e03c705c83a780176f1ca06f Mon Sep 17 00:00:00 2001 Message-Id: <1039263f503f5767e03c705c83a780176f1ca06f.1626339932.git.fweimer@redhat.com> Date: Thu, 15 Jul 2021 11:11:03 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (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.9 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, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP 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 partially fixes static-only NSS support (bug 27959): The dns module no longer needs dlopen. Support for disabling dlopen altogher remains to be added. This commit introduces module_load_builtin into nss/nss_module.c, which handles the common parts of loading the built-in nss_files and nss_dns modules. Reviewed-by: Carlos O'Donell Tested-by: Carlos O'Donell --- include/nss_dns.h | 13 +++++---- nss/nss_files_functions.c | 6 ---- nss/nss_module.c | 58 ++++++++++++++++++++++++++++---------- nss/nss_module.h | 10 +++++-- resolv/Makefile | 1 + resolv/nss_dns_functions.c | 40 ++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 28 deletions(-) create mode 100644 resolv/nss_dns_functions.c diff --git a/include/nss_dns.h b/include/nss_dns.h index 63b5853870..53205b27a6 100644 --- a/include/nss_dns.h +++ b/include/nss_dns.h @@ -24,13 +24,16 @@ NSS_DECLARE_MODULE_FUNCTIONS (dns) libc_hidden_proto (_nss_dns_getcanonname_r) -libc_hidden_proto (_nss_dns_gethostbyname3_r) -libc_hidden_proto (_nss_dns_gethostbyname2_r) -libc_hidden_proto (_nss_dns_gethostbyname_r) -libc_hidden_proto (_nss_dns_gethostbyname4_r) libc_hidden_proto (_nss_dns_gethostbyaddr2_r) libc_hidden_proto (_nss_dns_gethostbyaddr_r) -libc_hidden_proto (_nss_dns_getnetbyname_r) +libc_hidden_proto (_nss_dns_gethostbyname2_r) +libc_hidden_proto (_nss_dns_gethostbyname3_r) +libc_hidden_proto (_nss_dns_gethostbyname4_r) +libc_hidden_proto (_nss_dns_gethostbyname_r) libc_hidden_proto (_nss_dns_getnetbyaddr_r) +libc_hidden_proto (_nss_dns_getnetbyname_r) + +void __nss_dns_functions (nss_module_functions_untyped pointers) + attribute_hidden; #endif diff --git a/nss/nss_files_functions.c b/nss/nss_files_functions.c index 85720b4311..46040fff70 100644 --- a/nss/nss_files_functions.c +++ b/nss/nss_files_functions.c @@ -34,10 +34,4 @@ __nss_files_functions (nss_module_functions_untyped pointers) #undef DEFINE_NSS_FUNCTION #define DEFINE_NSS_FUNCTION(x) *fptr++ = _nss_files_##x; #include "function.def" - -#ifdef PTR_MANGLE - void **end = fptr; - for (fptr = pointers; fptr != end; ++fptr) - PTR_MANGLE (*fptr); -#endif } diff --git a/nss/nss_module.c b/nss/nss_module.c index 7ea5ad9887..b28cb94a6a 100644 --- a/nss/nss_module.c +++ b/nss/nss_module.c @@ -26,11 +26,13 @@ #include #include #include +#include +#include #include #include #include #include -#include +#include /* Suffix after .so of NSS service modules. This is a bit of magic, but we assume LIBNSS_FILES_SO looks like "libnss_files.so.2" and we @@ -111,20 +113,12 @@ static const function_name nss_function_name_array[] = #include "function.def" }; +/* Loads a built-in module, binding the symbols using the supplied + callback function. Always returns true. */ static bool -module_load_nss_files (struct nss_module *module) +module_load_builtin (struct nss_module *module, + void (*bind) (nss_module_functions_untyped)) { -#ifdef USE_NSCD - if (is_nscd) - { - void (*cb) (size_t, struct traced_file *) = nscd_init_cb; -# ifdef PTR_DEMANGLE - PTR_DEMANGLE (cb); -# endif - _nss_files_init (cb); - } -#endif - /* Initialize the function pointers, following the double-checked locking idiom. */ __libc_lock_lock (nss_module_list_lock); @@ -132,7 +126,13 @@ module_load_nss_files (struct nss_module *module) { case nss_module_uninitialized: case nss_module_failed: - __nss_files_functions (module->functions.untyped); + bind (module->functions.untyped); + +#ifdef PTR_MANGLE + for (int i = 0; i < nss_module_functions_count; ++i) + PTR_MANGLE (module->functions.untyped[i]); +#endif + module->handle = NULL; /* Synchronizes with unlocked __nss_module_load atomic_load_acquire. */ atomic_store_release (&module->state, nss_module_loaded); @@ -145,12 +145,38 @@ module_load_nss_files (struct nss_module *module) return true; } +/* Loads the built-in nss_files module. */ +static bool +module_load_nss_files (struct nss_module *module) +{ +#ifdef USE_NSCD + if (is_nscd) + { + void (*cb) (size_t, struct traced_file *) = nscd_init_cb; +# ifdef PTR_DEMANGLE + PTR_DEMANGLE (cb); +# endif + _nss_files_init (cb); + } +#endif + return module_load_builtin (module, __nss_files_functions); +} + +/* Loads the built-in nss_dns module. */ +static bool +module_load_nss_dns (struct nss_module *module) +{ + return module_load_builtin (module, __nss_dns_functions); +} + /* Internal implementation of __nss_module_load. */ static bool module_load (struct nss_module *module) { if (strcmp (module->name, "files") == 0) return module_load_nss_files (module); + if (strcmp (module->name, "dns") == 0) + return module_load_nss_dns (module); void *handle; { @@ -398,7 +424,9 @@ __nss_module_freeres (void) struct nss_module *current = nss_module_list; while (current != NULL) { - if (current->state == nss_module_loaded && current->handle != NULL) + /* Ignore built-in modules (which have a NULL handle). */ + if (current->state == nss_module_loaded + && current->handle != NULL) __libc_dlclose (current->handle); struct nss_module *next = current->next; diff --git a/nss/nss_module.h b/nss/nss_module.h index c1a1d90b60..b52c2935d2 100644 --- a/nss/nss_module.h +++ b/nss/nss_module.h @@ -33,10 +33,16 @@ struct nss_module_functions #include "function.def" }; +/* Number of elements of the nss_module_functions_untyped array. */ +enum + { + nss_module_functions_count = (sizeof (struct nss_module_functions) + / sizeof (void *)) + }; + /* Untyped version of struct nss_module_functions, for consistent processing purposes. */ -typedef void *nss_module_functions_untyped[sizeof (struct nss_module_functions) - / sizeof (void *)]; +typedef void *nss_module_functions_untyped[nss_module_functions_count]; /* Locate the nss_files functions, as if by dlopen/dlsym. */ void __nss_files_functions (nss_module_functions_untyped pointers) diff --git a/resolv/Makefile b/resolv/Makefile index dd0a98c74f..31d27454b4 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -48,6 +48,7 @@ routines := \ ns_name_unpack \ ns_samename \ nsap_addr \ + nss_dns_functions \ res-close \ res-name-checking \ res-state \ diff --git a/resolv/nss_dns_functions.c b/resolv/nss_dns_functions.c new file mode 100644 index 0000000000..158dafec90 --- /dev/null +++ b/resolv/nss_dns_functions.c @@ -0,0 +1,40 @@ +/* Direct access for nss_dns functions for NSS module loading. + Copyright (C) 2021 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 + +void +__nss_dns_functions (nss_module_functions_untyped pointers) +{ + struct nss_module_functions typed = + { + .getcanonname_r = &_nss_dns_getcanonname_r, + .gethostbyname3_r = &_nss_dns_gethostbyname3_r, + .gethostbyname2_r = &_nss_dns_gethostbyname2_r, + .gethostbyname_r = &_nss_dns_gethostbyname_r, + .gethostbyname4_r = &_nss_dns_gethostbyname4_r, + .gethostbyaddr2_r = &_nss_dns_gethostbyaddr2_r, + .gethostbyaddr_r = &_nss_dns_gethostbyaddr_r, + .getnetbyname_r = &_nss_dns_getnetbyname_r, + .getnetbyaddr_r = &_nss_dns_getnetbyaddr_r, + }; + + memcpy (pointers, &typed, sizeof (nss_module_functions_untyped)); +}