nss: Export nscd hash function as __nss_hash [BZ #22459]

This commit is contained in:
Florian Weimer 2017-11-23 14:08:11 +01:00
parent cccb6d4e87
commit 67f36c7922
12 changed files with 129 additions and 108 deletions

View File

@ -1,3 +1,21 @@
2017-11-23 Florian Weimer <fweimer@redhat.com>
[BZ #22459]
Export nscd hash function as __nss_hash.
* include/nss.h (__nss_hash): Declare.
* nis/nis_hash.c (__nis_hash): Call __nss_hash. Turn into compat
symbol.
* nscd/Makefile (aux, nscd-modules): Remove nscd_hash.
* nscd/cache.c (cache_search, cache_add): Call __nss_hash instead
of __nscd_hash.
* nscd/nscd_helper.c (__nscd_cache_search): Likewise.
* nscd/nscd_hash.h, nscd/nscd_hash.c: Remove files.
* nss/Makefiles (routines): Add nss_hash.
* nss/Versions (GLIBC_PRIVATE): Export __nss_hash.
* nss/nss_hash.c: Rename from nis/nis_hash.c.
(__nss_hash): Rename from __nis_hash. Define hidden alias.
* nis/rpcsvc/nislib.h (__nis_hash): Remove declaration.
2017-11-23 Florian Weimer <fweimer@redhat.com> 2017-11-23 Florian Weimer <fweimer@redhat.com>
[BZ #22478] [BZ #22478]

View File

@ -1,9 +1,12 @@
#ifndef _NSS_H #ifndef _NSS_H
#include <nss/nss.h> #include <nss/nss.h>
# ifndef _ISOMAC #ifndef _ISOMAC
#define NSS_INVALID_FIELD_CHARACTERS ":\n" # include <stddef.h>
# include <stdint.h>
# define NSS_INVALID_FIELD_CHARACTERS ":\n"
extern const char __nss_invalid_field_characters[] attribute_hidden; extern const char __nss_invalid_field_characters[] attribute_hidden;
_Bool __nss_valid_field (const char *value) attribute_hidden; _Bool __nss_valid_field (const char *value) attribute_hidden;
@ -11,5 +14,10 @@ _Bool __nss_valid_list_field (char **list) attribute_hidden;
const char *__nss_rewrite_field (const char *value, char **to_be_freed) const char *__nss_rewrite_field (const char *value, char **to_be_freed)
attribute_hidden; attribute_hidden;
# endif /* !_ISOMAC */ /* Compute a hash value for LENGTH bytes starting at KEY. This is the
hash function used by the nscd for the cache mapping files. */
uint32_t __nss_hash (const void *__key, size_t __length);
libc_hidden_proto (__nss_hash)
#endif /* !_ISOMAC */
#endif /* _NSS_H */ #endif /* _NSS_H */

View File

@ -1,6 +1,6 @@
/* Copyright (c) 1997-2017 Free Software Foundation, Inc. /* Forward __nis_hash calls to __nss_hash, for ABI compatibility.
Copyright (c) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -16,61 +16,18 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <stdint.h> #include <shlib-compat.h>
#include <rpcsvc/nis.h>
#if SHLIB_COMPAT (libnsl, GLIBC_2_1, GLIBC_2_27)
# include <nss.h>
/* This is from libc/db/hash/hash_func.c, hash3 is static there */
/*
* This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
* units. On the first time through the loop we get the "leftover bytes"
* (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
* all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
* this routine is heavily used enough, it's worth the ugly coding.
*
* OZ's original sdbm hash
*/
uint32_t uint32_t
__nis_hash (const void *keyarg, size_t len) __nis_hash (const void *keyarg, size_t len)
{ {
const u_char *key; return __nss_hash (keyarg, len);
size_t loop;
uint32_t h;
#define HASHC h = *key++ + 65599 * h
h = 0;
key = keyarg;
if (len > 0)
{
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1))
{
case 0:
do {
HASHC;
/* FALLTHROUGH */
case 7:
HASHC;
/* FALLTHROUGH */
case 6:
HASHC;
/* FALLTHROUGH */
case 5:
HASHC;
/* FALLTHROUGH */
case 4:
HASHC;
/* FALLTHROUGH */
case 3:
HASHC;
/* FALLTHROUGH */
case 2:
HASHC;
/* FALLTHROUGH */
case 1:
HASHC;
} while (--loop);
}
}
return h;
} }
compat_symbol (libnsl, __nis_hash, __nis_hash, GLIBC_2_1);
#endif

View File

@ -244,7 +244,6 @@ extern uint32_t __nis_default_ttl (char *) __THROW;
extern unsigned int __nis_default_access (char *, unsigned int) __THROW; extern unsigned int __nis_default_access (char *, unsigned int) __THROW;
extern fd_result *__nis_finddirectory (directory_obj *, const_nis_name) __THROW; extern fd_result *__nis_finddirectory (directory_obj *, const_nis_name) __THROW;
extern void __free_fdresult (fd_result *) __THROW; extern void __free_fdresult (fd_result *) __THROW;
extern uint32_t __nis_hash (const void *__keyarg, size_t __len) __THROW;
/* NIS+ cache locking */ /* NIS+ cache locking */
extern int __nis_lock_cache (void) __THROW; extern int __nis_lock_cache (void) __THROW;

View File

@ -25,7 +25,7 @@ include ../Makeconfig
ifneq ($(use-nscd),no) ifneq ($(use-nscd),no)
routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \ routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
nscd_initgroups nscd_getserv_r nscd_netgroup nscd_initgroups nscd_getserv_r nscd_netgroup
aux := nscd_helper nscd_hash aux := nscd_helper
endif endif
# To find xmalloc.c # To find xmalloc.c
@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
getsrvbynm_r getsrvbypt_r servicescache \ getsrvbynm_r getsrvbypt_r servicescache \
dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \ dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
xmalloc xstrdup aicache initgrcache gai res_hconf \ xmalloc xstrdup aicache initgrcache gai res_hconf \
netgroupcache nscd_hash netgroupcache
ifeq ($(build-nscd)$(have-thread-library),yesyes) ifeq ($(build-nscd)$(have-thread-library),yesyes)

View File

@ -29,10 +29,10 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <nss.h>
#include "nscd.h" #include "nscd.h"
#include "dbg_log.h" #include "dbg_log.h"
#include "nscd_hash.h"
/* Wrapper functions with error checking for standard functions. */ /* Wrapper functions with error checking for standard functions. */
@ -74,7 +74,7 @@ struct datahead *
cache_search (request_type type, const void *key, size_t len, cache_search (request_type type, const void *key, size_t len,
struct database_dyn *table, uid_t owner) struct database_dyn *table, uid_t owner)
{ {
unsigned long int hash = __nscd_hash (key, len) % table->head->module; unsigned long int hash = __nss_hash (key, len) % table->head->module;
unsigned long int nsearched = 0; unsigned long int nsearched = 0;
struct datahead *result = NULL; struct datahead *result = NULL;
@ -153,7 +153,7 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
first ? _(" (first)") : ""); first ? _(" (first)") : "");
} }
unsigned long int hash = __nscd_hash (key, len) % table->head->module; unsigned long int hash = __nss_hash (key, len) % table->head->module;
struct hashentry *newp; struct hashentry *newp;
newp = mempool_alloc (table, sizeof (struct hashentry), 0); newp = mempool_alloc (table, sizeof (struct hashentry), 0);

View File

@ -1,19 +0,0 @@
/* Copyright (C) 2017 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
<http://www.gnu.org/licenses/>. */
#define __nis_hash __nscd_hash
#include <nis/nis_hash.c>

View File

@ -1,21 +0,0 @@
/* Copyright (C) 2017 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
<http://www.gnu.org/licenses/>. */
#include <stdint.h>
extern uint32_t __nscd_hash (const void *__keyarg, size_t __len)
attribute_hidden;

View File

@ -36,10 +36,9 @@
#include <sys/un.h> #include <sys/un.h>
#include <not-cancel.h> #include <not-cancel.h>
#include <kernel-features.h> #include <kernel-features.h>
#include <nss.h>
#include "nscd-client.h" #include "nscd-client.h"
#include "nscd_hash.h"
/* Extra time we wait if the socket is still receiving data. This /* Extra time we wait if the socket is still receiving data. This
value is in milliseconds. Note that the other side is nscd on the value is in milliseconds. Note that the other side is nscd on the
@ -451,7 +450,7 @@ struct datahead *
__nscd_cache_search (request_type type, const char *key, size_t keylen, __nscd_cache_search (request_type type, const char *key, size_t keylen,
const struct mapped_database *mapped, size_t datalen) const struct mapped_database *mapped, size_t datalen)
{ {
unsigned long int hash = __nscd_hash (key, keylen) % mapped->head->module; unsigned long int hash = __nss_hash (key, keylen) % mapped->head->module;
size_t datasize = mapped->datasize; size_t datasize = mapped->datasize;
ref_t trail = mapped->head->array[hash]; ref_t trail = mapped->head->array[hash];

View File

@ -28,7 +28,7 @@ headers := nss.h
routines = nsswitch getnssent getnssent_r digits_dots \ routines = nsswitch getnssent getnssent_r digits_dots \
valid_field valid_list_field rewrite_field \ valid_field valid_list_field rewrite_field \
$(addsuffix -lookup,$(databases)) \ $(addsuffix -lookup,$(databases)) \
compat-lookup compat-lookup nss_hash
# These are the databases that go through nss dispatch. # These are the databases that go through nss dispatch.
# Caution: if you add a database here, you must add its real name # Caution: if you add a database here, you must add its real name

View File

@ -15,6 +15,7 @@ libc {
__nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2; __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2;
__nss_services_lookup2; __nss_next2; __nss_lookup; __nss_services_lookup2; __nss_next2; __nss_lookup;
__nss_hash;
} }
} }

79
nss/nss_hash.c Normal file
View File

@ -0,0 +1,79 @@
/* Copyright (c) 1997-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
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
<http://www.gnu.org/licenses/>. */
#include <nss.h>
/* This is from libc/db/hash/hash_func.c, hash3 is static there */
/*
* This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
* units. On the first time through the loop we get the "leftover bytes"
* (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
* all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
* this routine is heavily used enough, it's worth the ugly coding.
*
* OZ's original sdbm hash
*/
uint32_t
__nss_hash (const void *keyarg, size_t len)
{
const unsigned char *key;
size_t loop;
uint32_t h;
#define HASHC h = *key++ + 65599 * h
h = 0;
key = keyarg;
if (len > 0)
{
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1))
{
case 0:
do
{
HASHC;
/* FALLTHROUGH */
case 7:
HASHC;
/* FALLTHROUGH */
case 6:
HASHC;
/* FALLTHROUGH */
case 5:
HASHC;
/* FALLTHROUGH */
case 4:
HASHC;
/* FALLTHROUGH */
case 3:
HASHC;
/* FALLTHROUGH */
case 2:
HASHC;
/* FALLTHROUGH */
case 1:
HASHC;
}
while (--loop);
}
}
return h;
}
libc_hidden_def (__nss_hash)