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",
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to