mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
nss: Directly load nss_dns, without going through dlsym/dlopen
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 <carlos@redhat.com> Tested-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
@ -24,13 +24,16 @@
|
|||||||
NSS_DECLARE_MODULE_FUNCTIONS (dns)
|
NSS_DECLARE_MODULE_FUNCTIONS (dns)
|
||||||
|
|
||||||
libc_hidden_proto (_nss_dns_getcanonname_r)
|
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_gethostbyaddr2_r)
|
||||||
libc_hidden_proto (_nss_dns_gethostbyaddr_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_getnetbyaddr_r)
|
||||||
|
libc_hidden_proto (_nss_dns_getnetbyname_r)
|
||||||
|
|
||||||
|
void __nss_dns_functions (nss_module_functions_untyped pointers)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,10 +34,4 @@ __nss_files_functions (nss_module_functions_untyped pointers)
|
|||||||
#undef DEFINE_NSS_FUNCTION
|
#undef DEFINE_NSS_FUNCTION
|
||||||
#define DEFINE_NSS_FUNCTION(x) *fptr++ = _nss_files_##x;
|
#define DEFINE_NSS_FUNCTION(x) *fptr++ = _nss_files_##x;
|
||||||
#include "function.def"
|
#include "function.def"
|
||||||
|
|
||||||
#ifdef PTR_MANGLE
|
|
||||||
void **end = fptr;
|
|
||||||
for (fptr = pointers; fptr != end; ++fptr)
|
|
||||||
PTR_MANGLE (*fptr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,13 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <gnu/lib-names.h>
|
#include <gnu/lib-names.h>
|
||||||
#include <libc-lock.h>
|
#include <libc-lock.h>
|
||||||
|
#include <nss_dns.h>
|
||||||
|
#include <nss_files.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <nss_files.h>
|
#include <sysdep.h>
|
||||||
|
|
||||||
/* Suffix after .so of NSS service modules. This is a bit of magic,
|
/* 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
|
but we assume LIBNSS_FILES_SO looks like "libnss_files.so.2" and we
|
||||||
@ -111,6 +113,39 @@ static const function_name nss_function_name_array[] =
|
|||||||
#include "function.def"
|
#include "function.def"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Loads a built-in module, binding the symbols using the supplied
|
||||||
|
callback function. Always returns true. */
|
||||||
|
static bool
|
||||||
|
module_load_builtin (struct nss_module *module,
|
||||||
|
void (*bind) (nss_module_functions_untyped))
|
||||||
|
{
|
||||||
|
/* Initialize the function pointers, following the double-checked
|
||||||
|
locking idiom. */
|
||||||
|
__libc_lock_lock (nss_module_list_lock);
|
||||||
|
switch ((enum nss_module_state) atomic_load_acquire (&module->state))
|
||||||
|
{
|
||||||
|
case nss_module_uninitialized:
|
||||||
|
case nss_module_failed:
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
case nss_module_loaded:
|
||||||
|
/* Nothing to clean up. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__libc_lock_unlock (nss_module_list_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loads the built-in nss_files module. */
|
||||||
static bool
|
static bool
|
||||||
module_load_nss_files (struct nss_module *module)
|
module_load_nss_files (struct nss_module *module)
|
||||||
{
|
{
|
||||||
@ -124,25 +159,14 @@ module_load_nss_files (struct nss_module *module)
|
|||||||
_nss_files_init (cb);
|
_nss_files_init (cb);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return module_load_builtin (module, __nss_files_functions);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the function pointers, following the double-checked
|
/* Loads the built-in nss_dns module. */
|
||||||
locking idiom. */
|
static bool
|
||||||
__libc_lock_lock (nss_module_list_lock);
|
module_load_nss_dns (struct nss_module *module)
|
||||||
switch ((enum nss_module_state) atomic_load_acquire (&module->state))
|
{
|
||||||
{
|
return module_load_builtin (module, __nss_dns_functions);
|
||||||
case nss_module_uninitialized:
|
|
||||||
case nss_module_failed:
|
|
||||||
__nss_files_functions (module->functions.untyped);
|
|
||||||
module->handle = NULL;
|
|
||||||
/* Synchronizes with unlocked __nss_module_load atomic_load_acquire. */
|
|
||||||
atomic_store_release (&module->state, nss_module_loaded);
|
|
||||||
break;
|
|
||||||
case nss_module_loaded:
|
|
||||||
/* Nothing to clean up. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
__libc_lock_unlock (nss_module_list_lock);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal implementation of __nss_module_load. */
|
/* Internal implementation of __nss_module_load. */
|
||||||
@ -151,6 +175,8 @@ module_load (struct nss_module *module)
|
|||||||
{
|
{
|
||||||
if (strcmp (module->name, "files") == 0)
|
if (strcmp (module->name, "files") == 0)
|
||||||
return module_load_nss_files (module);
|
return module_load_nss_files (module);
|
||||||
|
if (strcmp (module->name, "dns") == 0)
|
||||||
|
return module_load_nss_dns (module);
|
||||||
|
|
||||||
void *handle;
|
void *handle;
|
||||||
{
|
{
|
||||||
@ -398,7 +424,9 @@ __nss_module_freeres (void)
|
|||||||
struct nss_module *current = nss_module_list;
|
struct nss_module *current = nss_module_list;
|
||||||
while (current != NULL)
|
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);
|
__libc_dlclose (current->handle);
|
||||||
|
|
||||||
struct nss_module *next = current->next;
|
struct nss_module *next = current->next;
|
||||||
|
@ -33,10 +33,16 @@ struct nss_module_functions
|
|||||||
#include "function.def"
|
#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
|
/* Untyped version of struct nss_module_functions, for consistent
|
||||||
processing purposes. */
|
processing purposes. */
|
||||||
typedef void *nss_module_functions_untyped[sizeof (struct nss_module_functions)
|
typedef void *nss_module_functions_untyped[nss_module_functions_count];
|
||||||
/ sizeof (void *)];
|
|
||||||
|
|
||||||
/* Locate the nss_files functions, as if by dlopen/dlsym. */
|
/* Locate the nss_files functions, as if by dlopen/dlsym. */
|
||||||
void __nss_files_functions (nss_module_functions_untyped pointers)
|
void __nss_files_functions (nss_module_functions_untyped pointers)
|
||||||
|
@ -48,6 +48,7 @@ routines := \
|
|||||||
ns_name_unpack \
|
ns_name_unpack \
|
||||||
ns_samename \
|
ns_samename \
|
||||||
nsap_addr \
|
nsap_addr \
|
||||||
|
nss_dns_functions \
|
||||||
res-close \
|
res-close \
|
||||||
res-name-checking \
|
res-name-checking \
|
||||||
res-state \
|
res-state \
|
||||||
|
40
resolv/nss_dns_functions.c
Normal file
40
resolv/nss_dns_functions.c
Normal file
@ -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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <nss/nss_module.h>
|
||||||
|
#include <nss_dns.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
Reference in New Issue
Block a user