aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-05-02 15:25:20 +0200
committerAurelien Jarno <aurelien@aurel32.net>2016-05-11 16:03:38 +0200
commita64be6fb2f1317ce7039a4bb8638bd0c30c31e28 (patch)
treeae526533fc85b1705fb5935e30a0d4b54f7bf345
parentccc3d71b28c2928df0b12bbed01f88a9e3e1f6f0 (diff)
downloadglibc-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--ChangeLog25
-rw-r--r--NEWS4
-rw-r--r--hesiod/Makefile2
-rw-r--r--hesiod/hesiod.c85
-rw-r--r--hesiod/hesiod.h30
-rw-r--r--hesiod/hesiod_p.h22
-rw-r--r--hesiod/nss_hesiod/hesiod-grp.c8
-rw-r--r--hesiod/nss_hesiod/hesiod-init.c38
-rw-r--r--hesiod/nss_hesiod/hesiod-proto.c5
-rw-r--r--hesiod/nss_hesiod/hesiod-pwd.c5
-rw-r--r--hesiod/nss_hesiod/hesiod-service.c5
-rw-r--r--hesiod/nss_hesiod/nss_hesiod.h20
12 files changed, 91 insertions, 158 deletions
diff --git a/ChangeLog b/ChangeLog
index 97b120e..62794f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 99ff28a..94b731f 100644
--- a/NEWS
+++ b/NEWS
@@ -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);