diff options
author | Florian Weimer <fweimer@redhat.com> | 2016-05-02 15:25:20 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2016-05-11 16:03:38 +0200 |
commit | a64be6fb2f1317ce7039a4bb8638bd0c30c31e28 (patch) | |
tree | ae526533fc85b1705fb5935e30a0d4b54f7bf345 | |
parent | ccc3d71b28c2928df0b12bbed01f88a9e3e1f6f0 (diff) | |
download | glibc-a64be6fb2f1317ce7039a4bb8638bd0c30c31e28.zip glibc-a64be6fb2f1317ce7039a4bb8638bd0c30c31e28.tar.gz glibc-a64be6fb2f1317ce7039a4bb8638bd0c30c31e28.tar.bz2 |
hesiod: Always use thread-local resolver state [BZ #19573]
The Hesiod implementation imported into glibc was enhanced
to support caller-supplied resolver states. But its only
consumer is nss_hesiod, and it supplies the thread-local
resolver state. Therefore, this commit changes the Hesiod
implementation to use the thread-local resolver state (_res)
directly. This fixes bug 19573 because the Hesiod
implementation no longer has to initialize and free any
resolver state.
To avoid any risk of interposition of ABI-incompatible Hesiod
function implementations, this commit marks the Hesiod functions
as hidden. (They were already hidden using a linker version
script.)
(cherry picked from commit 5018f16c6205404ba3aa7298dc8a3d45fbd46bfc)
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | hesiod/Makefile | 2 | ||||
-rw-r--r-- | hesiod/hesiod.c | 85 | ||||
-rw-r--r-- | hesiod/hesiod.h | 30 | ||||
-rw-r--r-- | hesiod/hesiod_p.h | 22 | ||||
-rw-r--r-- | hesiod/nss_hesiod/hesiod-grp.c | 8 | ||||
-rw-r--r-- | hesiod/nss_hesiod/hesiod-init.c | 38 | ||||
-rw-r--r-- | hesiod/nss_hesiod/hesiod-proto.c | 5 | ||||
-rw-r--r-- | hesiod/nss_hesiod/hesiod-pwd.c | 5 | ||||
-rw-r--r-- | hesiod/nss_hesiod/hesiod-service.c | 5 | ||||
-rw-r--r-- | hesiod/nss_hesiod/nss_hesiod.h | 20 |
12 files changed, 91 insertions, 158 deletions
@@ -1,5 +1,30 @@ 2016-05-02 Florian Weimer <fweimer@redhat.com> + [BZ #19573] + * hesiod/Makefile (libnss_hesiod-routines): Remove hesiod-init. + * hesiod/nss_hesiod/hesiod-init.c: Remove file. + * hesiod/nss_hesiod/nss_hesiod.h: Likewise. + * hesiod/hesiod.h (__hesiod_res_get, __hesiod_res_set): Remove. + (hesiod_init, hesiod_end, hesiod_to_bind, hesiod_resolve) + (hesiod_free_list): Mark as hidden. + * hesiod/hesiod_p (struct hesiod_p): Remove res, free_res, + res_set, res_get. + * hesiod/hesiod.c: Remove unnecessary forward declarations. + (init, __hesiod_res_get, __hesiod_res_set): Remove. + (hesiod_init): Remove obsolete res_ninit call. + (hesiod_end): Do not free resolver state. Do not invoke callback. + (hesiod_bind): Do not call init. + (get_txt_records): Use res_mkquery, res_send instead of + res_nmkquery, res_nsend. + * hesiod/nss_hesiod/hesiod-grp.c (lookup): Call hesiod_init + instead of _nss_hesiod_init. + (_nss_hesiod_initgroups_dyn): Likewise. + * hesiod/nss_hesiod/hesiod-proto.c (lookup): Likewise. + * hesiod/nss_hesiod/hesiod-pwd.c (lookup): Likewise. + * hesiod/nss_hesiod/hesiod-service.c (lookup): Likewise. + +2016-05-02 Florian Weimer <fweimer@redhat.com> + * hesiod/hesiod.h: Remove RCS keyword. * hesiod/hesiod_p.h: Likewise. * hesiod/hesiod.c: Likewise. @@ -25,8 +25,8 @@ Version 2.22.1 17905, 18420, 18421, 18480, 18589, 18743, 18778, 18781, 18787, 18796, 18870, 18887, 18921, 18928, 18969, 18985, 19003, 19018, 19048, 19058, - 19174, 19178, 19182, 19243, 19590, 19682, 19791, 19822, 19853, 19879, - 19779, 20010. + 19174, 19178, 19182, 19243, 19573, 19590, 19682, 19791, 19822, 19853, + 19879, 19779, 20010. * The getnetbyname implementation in nss_dns had a potentially unbounded alloca call (in the form of a call to strdupa), leading to a stack diff --git a/hesiod/Makefile b/hesiod/Makefile index ac0bc01..cdd7730 100644 --- a/hesiod/Makefile +++ b/hesiod/Makefile @@ -28,7 +28,7 @@ extra-libs-others = $(extra-libs) subdir-dirs = nss_hesiod vpath %.c nss_hesiod -libnss_hesiod-routines := hesiod hesiod-grp hesiod-init hesiod-proto \ +libnss_hesiod-routines := hesiod hesiod-grp hesiod-proto \ hesiod-pwd hesiod-service # Build only shared library libnss_hesiod-inhibit-o = $(filter-out .os,$(object-suffixes)) diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c index 76b9bef..5b13b3f 100644 --- a/hesiod/hesiod.c +++ b/hesiod/hesiod.c @@ -1,3 +1,20 @@ +/* Copyright (C) 1997-2016 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/>. */ + /* * Copyright (c) 1996,1999 by Internet Software Consortium. * @@ -48,18 +65,9 @@ /* Forward */ -int hesiod_init(void **context); -void hesiod_end(void *context); -char * hesiod_to_bind(void *context, const char *name, - const char *type); -char ** hesiod_resolve(void *context, const char *name, - const char *type); -void hesiod_free_list(void *context, char **list); - static int parse_config_file(struct hesiod_p *ctx, const char *filename); static char ** get_txt_records(struct hesiod_p *ctx, int class, const char *name); -static int init(struct hesiod_p *ctx); /* Public */ @@ -78,7 +86,6 @@ hesiod_init(void **context) { ctx->LHS = NULL; ctx->RHS = NULL; - ctx->res = NULL; /* Set default query classes. */ ctx->classes[0] = C_IN; ctx->classes[1] = C_HS; @@ -127,11 +134,6 @@ hesiod_init(void **context) { goto cleanup; } -#if 0 - if (res_ninit(ctx->res) < 0) - goto cleanup; -#endif - *context = ctx; return (0); @@ -148,12 +150,8 @@ hesiod_end(void *context) { struct hesiod_p *ctx = (struct hesiod_p *) context; int save_errno = errno; - if (ctx->res) - res_nclose(ctx->res); free(ctx->RHS); free(ctx->LHS); - if (ctx->res && ctx->free_res) - (*ctx->free_res)(ctx->res); free(ctx); __set_errno(save_errno); } @@ -228,10 +226,6 @@ hesiod_resolve(void *context, const char *name, const char *type) { if (bindname == NULL) return (NULL); - if (init(ctx) == -1) { - free(bindname); - return (NULL); - } retvec = get_txt_records(ctx, ctx->classes[0], bindname); @@ -361,13 +355,13 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) { /* * Construct the query and send it. */ - n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0, + n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0, NULL, qbuf, MAX_HESRESP); if (n < 0) { __set_errno(EMSGSIZE); return (NULL); } - n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP); + n = res_send(qbuf, n, abuf, MAX_HESRESP); if (n < 0) { __set_errno(ECONNREFUSED); return (NULL); @@ -460,44 +454,3 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) { free(list); return (NULL); } - -struct __res_state * -__hesiod_res_get(void *context) { - struct hesiod_p *ctx = context; - - if (!ctx->res) { - struct __res_state *res; - res = (struct __res_state *)calloc(1, sizeof *res); - if (res == NULL) - return (NULL); - __hesiod_res_set(ctx, res, free); - } - - return (ctx->res); -} - -void -__hesiod_res_set(void *context, struct __res_state *res, - void (*free_res)(void *)) { - struct hesiod_p *ctx = context; - - if (ctx->res && ctx->free_res) { - res_nclose(ctx->res); - (*ctx->free_res)(ctx->res); - } - - ctx->res = res; - ctx->free_res = free_res; -} - -static int -init(struct hesiod_p *ctx) { - - if (!ctx->res && !__hesiod_res_get(ctx)) - return (-1); - - if (__res_maybe_init (ctx->res, 0) == -1) - return (-1); - - return (0); -} diff --git a/hesiod/hesiod.h b/hesiod/hesiod.h index cb742b0..c4f5356 100644 --- a/hesiod/hesiod.h +++ b/hesiod/hesiod.h @@ -1,3 +1,20 @@ +/* Copyright (C) 1997-2016 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/>. */ + /* * Copyright (c) 1996,1999 by Internet Software Consortium. * @@ -22,15 +39,12 @@ #ifndef _HESIOD_H_INCLUDED #define _HESIOD_H_INCLUDED -int hesiod_init (void **context); -void hesiod_end (void *context); +int hesiod_init (void **context) attribute_hidden; +void hesiod_end (void *context) attribute_hidden; char * hesiod_to_bind (void *context, const char *name, - const char *type); + const char *type) attribute_hidden; char ** hesiod_resolve (void *context, const char *name, - const char *type); -void hesiod_free_list (void *context, char **list); -struct __res_state * __hesiod_res_get (void *context); -void __hesiod_res_set (void *context, struct __res_state *, - void (*)(void *)); + const char *type) attribute_hidden; +void hesiod_free_list (void *context, char **list) attribute_hidden; #endif /*_HESIOD_H_INCLUDED*/ diff --git a/hesiod/hesiod_p.h b/hesiod/hesiod_p.h index 7bd2919..1d6d826 100644 --- a/hesiod/hesiod_p.h +++ b/hesiod/hesiod_p.h @@ -1,3 +1,20 @@ +/* Copyright (C) 1997-2016 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/>. */ + /* * Copyright (c) 1996,1999 by Internet Software Consortium. * @@ -32,11 +49,6 @@ struct hesiod_p { char * LHS; /* normally ".ns" */ char * RHS; /* AKA the default hesiod domain */ - struct __res_state * res; /* resolver context */ - void (*free_res)(void *); - void (*res_set)(struct hesiod_p *, struct __res_state *, - void (*)(void *)); - struct __res_state * (*res_get)(struct hesiod_p *); int classes[2]; /* The class search order. */ }; diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c index 0909a85..6ccb3bb 100644 --- a/hesiod/nss_hesiod/hesiod-grp.c +++ b/hesiod/nss_hesiod/hesiod-grp.c @@ -26,8 +26,6 @@ #include <string.h> #include <sys/param.h> -#include "nss_hesiod.h" - /* Get the declaration of the parser function. */ #define ENTNAME grent #define STRUCTURE group @@ -58,8 +56,7 @@ lookup (const char *name, const char *type, struct group *grp, size_t len; int olderr = errno; - context = _nss_hesiod_init (); - if (context == NULL) + if (hesiod_init (&context) < 0) return NSS_STATUS_UNAVAIL; list = hesiod_resolve (context, name, type); @@ -179,8 +176,7 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, gid_t *groups = *groupsp; int save_errno; - context = _nss_hesiod_init (); - if (context == NULL) + if (hesiod_init (&context) < 0) return NSS_STATUS_UNAVAIL; list = hesiod_resolve (context, user, "grplist"); diff --git a/hesiod/nss_hesiod/hesiod-init.c b/hesiod/nss_hesiod/hesiod-init.c deleted file mode 100644 index 755d3ad..0000000 --- a/hesiod/nss_hesiod/hesiod-init.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2000-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 2000. - - 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 <sys/cdefs.h> /* Needs to come before <hesiod.h>. */ -#include <hesiod.h> -#include <resolv.h> -#include <stddef.h> - -#include "nss_hesiod.h" - -void * -_nss_hesiod_init (void) -{ - void *context; - - if (hesiod_init (&context) == -1) - return NULL; - - /* Use the default (per-thread) resolver state. */ - __hesiod_res_set (context, &_res, NULL); - - return context; -} diff --git a/hesiod/nss_hesiod/hesiod-proto.c b/hesiod/nss_hesiod/hesiod-proto.c index 4073ee3..fcb09d1 100644 --- a/hesiod/nss_hesiod/hesiod-proto.c +++ b/hesiod/nss_hesiod/hesiod-proto.c @@ -25,8 +25,6 @@ #include <stdlib.h> #include <string.h> -#include "nss_hesiod.h" - /* Declare a parser for Hesiod protocol entries. Although the format of the entries is identical to those in /etc/protocols, here is no predefined parser for us to use. */ @@ -68,8 +66,7 @@ lookup (const char *name, const char *type, struct protoent *proto, int found; int olderr = errno; - context = _nss_hesiod_init (); - if (context == NULL) + if (hesiod_init (&context) < 0) return NSS_STATUS_UNAVAIL; list = hesiod_resolve (context, name, type); diff --git a/hesiod/nss_hesiod/hesiod-pwd.c b/hesiod/nss_hesiod/hesiod-pwd.c index 94a8666..948a575 100644 --- a/hesiod/nss_hesiod/hesiod-pwd.c +++ b/hesiod/nss_hesiod/hesiod-pwd.c @@ -24,8 +24,6 @@ #include <stdlib.h> #include <string.h> -#include "nss_hesiod.h" - /* Get the declaration of the parser function. */ #define ENTNAME pwent #define STRUCTURE passwd @@ -56,8 +54,7 @@ lookup (const char *name, const char *type, struct passwd *pwd, size_t len; int olderr = errno; - context = _nss_hesiod_init (); - if (context == NULL) + if (hesiod_init (&context) < 0) return NSS_STATUS_UNAVAIL; list = hesiod_resolve (context, name, type); diff --git a/hesiod/nss_hesiod/hesiod-service.c b/hesiod/nss_hesiod/hesiod-service.c index 0e53b77..dc89c2d 100644 --- a/hesiod/nss_hesiod/hesiod-service.c +++ b/hesiod/nss_hesiod/hesiod-service.c @@ -25,8 +25,6 @@ #include <stdlib.h> #include <string.h> -#include "nss_hesiod.h" - /* Hesiod uses a format for service entries that differs from the traditional format. We therefore declare our own parser. */ @@ -69,8 +67,7 @@ lookup (const char *name, const char *type, const char *protocol, int found; int olderr = errno; - context = _nss_hesiod_init (); - if (context == NULL) + if (hesiod_init (&context) < 0) return NSS_STATUS_UNAVAIL; list = hesiod_resolve (context, name, type); diff --git a/hesiod/nss_hesiod/nss_hesiod.h b/hesiod/nss_hesiod/nss_hesiod.h deleted file mode 100644 index 79115e0..0000000 --- a/hesiod/nss_hesiod/nss_hesiod.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 2000-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 2000. - - 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/>. */ - -/* Initialize a Hesiod context. */ -extern void *_nss_hesiod_init (void); |