svn commit: r192911 - in head/lib/libc: include net

Zachary Loafman zml at FreeBSD.org
Wed May 27 17:02:01 UTC 2009


Author: zml
Date: Wed May 27 17:01:59 2009
New Revision: 192911
URL: http://svn.freebsd.org/changeset/base/192911

Log:
  Fix an issue when nss fallback routines are used in a multithreaded application.
  
  Reviewed by:        bushman
  Approved by:        dfr (mentor)

Modified:
  head/lib/libc/include/nss_tls.h
  head/lib/libc/net/nsdispatch.c

Modified: head/lib/libc/include/nss_tls.h
==============================================================================
--- head/lib/libc/include/nss_tls.h	Wed May 27 16:44:43 2009	(r192910)
+++ head/lib/libc/include/nss_tls.h	Wed May 27 17:01:59 2009	(r192911)
@@ -67,6 +67,7 @@ name##_getstate(struct name##_state **p)
 	*p = calloc(1, sizeof(**p));				\
 	if (*p == NULL)						\
 		return (ENOMEM);				\
+	memset(*p, 0, sizeof(**p));				\
 	rv = _pthread_setspecific(name##_state_key, *p);	\
 	if (rv != 0) {						\
 		free(*p);					\

Modified: head/lib/libc/net/nsdispatch.c
==============================================================================
--- head/lib/libc/net/nsdispatch.c	Wed May 27 16:44:43 2009	(r192910)
+++ head/lib/libc/net/nsdispatch.c	Wed May 27 17:01:59 2009	(r192911)
@@ -80,12 +80,14 @@ __FBSDID("$FreeBSD$");
 #define _NS_PRIVATE
 #include <nsswitch.h>
 #include <pthread.h>
+#include <pthread_np.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
 #include "un-namespace.h"
+#include "nss_tls.h"
 #include "libc_private.h"
 #ifdef NS_CACHING
 #include "nscache.h"
@@ -143,7 +145,11 @@ static	void			*nss_cache_cycle_preventio
  *     which in turn calls nsdispatch, which should call fallback
  *     function) are not supported
  */
-static	int			fallback_dispatch = 0;
+struct fb_state {
+	int	fb_dispatch;
+};
+static	void	fb_endstate(void *);
+NSS_TLS_HANDLING(fb);
 
 /*
  * Attempt to spew relatively uniform messages to syslog.
@@ -598,6 +604,11 @@ nss_method_lookup(const char *source, co
 	return (NULL);
 }
 
+static void
+fb_endstate(void *p)
+{
+	free(p);
+}
 
 __weak_reference(_nsdispatch, nsdispatch);
 
@@ -611,6 +622,7 @@ _nsdispatch(void *retval, const ns_dtab 
 	nss_method	 method, fb_method;
 	void		*mdata;
 	int		 isthreaded, serrno, i, result, srclistsize;
+	struct fb_state	*st;
 
 #ifdef NS_CACHING
 	nss_cache_data	 cache_data;
@@ -630,12 +642,19 @@ _nsdispatch(void *retval, const ns_dtab 
 			goto fin;
 		}
 	}
+
+	result = fb_getstate(&st);
+	if (result != 0) {
+		result = NS_UNAVAIL;
+		goto fin;
+	}
+
 	result = nss_configure();
 	if (result != 0) {
 		result = NS_UNAVAIL;
 		goto fin;
 	}
-	if (fallback_dispatch == 0) {
+	if (st->fb_dispatch == 0) {
 		dbt = vector_search(&database, _nsmap, _nsmapsize, sizeof(*_nsmap),
 		    string_compare);
 		fb_method = nss_method_lookup(NSSRC_FALLBACK, database,
@@ -702,12 +721,12 @@ _nsdispatch(void *retval, const ns_dtab 
 				break;
 		} else {
 			if (fb_method != NULL) {
-				fallback_dispatch = 1;
+				st->fb_dispatch = 1;
 				va_start(ap, defaults);
 				result = fb_method(retval,
 				    (void *)srclist[i].name, ap);
 				va_end(ap);
-				fallback_dispatch = 0;
+				st->fb_dispatch = 0;
 			} else
 				nss_log(LOG_DEBUG, "%s, %s, %s, not found, "
 				    "and no fallback provided",


More information about the svn-src-head mailing list