rpms/nss_ldap/devel nss_ldap-257-over-recursion.patch,NONE,1.1

Nalin Somabhai Dahyabhai (nalin) fedora-extras-commits at redhat.com
Thu Sep 20 19:07:39 UTC 2007


Author: nalin

Update of /cvs/pkgs/rpms/nss_ldap/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv25093

Added Files:
	nss_ldap-257-over-recursion.patch 
Log Message:
- attempt to avoid over-recursion from nss_ldap ending up needing to call
  itself during initialization, preferable to infinite-recurse-then-crash


nss_ldap-257-over-recursion.patch:

--- NEW FILE nss_ldap-257-over-recursion.patch ---
This isn't particularly elegant or exhaustive, and the maximum recursion depth
is purely an arbitrary value, but keeping a per-thread depth count manages to
avoid infinite recursion crashes which happen when we hit nesting through
nss_ldap->libldap->gethostbyXXX->nss_ldap calls.

diff -ur nss_ldap/configure.in nss_ldap/configure.in
--- nss_ldap/configure.in	2007-09-20 14:35:18.000000000 -0400
+++ nss_ldap/configure.in	2007-09-20 13:43:49.000000000 -0400
@@ -243,6 +243,17 @@
 	],
 	AC_MSG_RESULT(no))
 
+AC_MSG_CHECKING(for thread-local storage)
+AC_TRY_COMPILE([#ifdef HAVE_PTHREAD_H
+	#include <pthread.h>
+	#endif],
+	[static __thread int foo = 1;],
+	[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_THREAD_LOCAL_STORAGE,1,[Define if your toolchain supports thread-local storage.])
+	],
+	AC_MSG_RESULT(no))
+
 AC_MSG_CHECKING(for socklen_t)
 AC_TRY_COMPILE([#include <sys/types.h>
 	#include <sys/socket.h>],
diff -ur nss_ldap/ldap-nss.c nss_ldap/ldap-nss.c
--- nss_ldap-257/ldap-nss.c	2007-09-20 14:35:18.000000000 -0400
+++ nss_ldap-257/ldap-nss.c	2007-09-20 14:33:01.000000000 -0400
@@ -119,6 +120,11 @@
 
 NSS_LDAP_DEFINE_LOCK (__lock);
 
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+static __thread int _nss_ldap_init_recursion_depth;
+static __thread int _nss_ldap_search_recursion_depth;
+#endif
+
 /*
  * the configuration is read by the first call to do_open().
  * Pointers to elements of the list are passed around but should not
@@ -1100,6 +1106,19 @@
   NSS_STATUS stat;
   int sd=-1;
 
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  if (_nss_ldap_init_recursion_depth > 5)
+    {
+      /* the reasoning here is just a guess, but why else? */
+      syslog (LOG_ERR, "nss_ldap: unable to connect to DSA without "
+	      "information which may need to be retrieved from the DSA");
+      debug ("<=> do_init: recursed too far, failing");
+      return NSS_NOTFOUND;
+    }
+
+  _nss_ldap_init_recursion_depth++;
+#endif
+
   debug ("==> do_init");
 
   if (_nss_ldap_validateconfig (__config) != NSS_SUCCESS)
@@ -1227,6 +1246,9 @@
       if (__session.ls_state == LS_CONNECTED_TO_DSA)
 	{
 	  debug ("<== do_init (cached session)");
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+	  _nss_ldap_init_recursion_depth--;
+#endif
 	  return NSS_SUCCESS;
 	}
     }
@@ -1239,6 +1261,9 @@
   if (pthread_once (&__once, do_atfork_setup) != 0)
     {
       debug ("<== do_init (pthread_once failed)");
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+      _nss_ldap_init_recursion_depth--;
+#endif
       return NSS_UNAVAIL;
     }
 #elif defined(HAVE_PTHREAD_ATFORK) && ( defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) )
@@ -1280,6 +1305,9 @@
 	{
 	  debug ("<== do_init (failed to read config)");
 	  __config = NULL;
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+          _nss_ldap_init_recursion_depth--;
+#endif
 	  return NSS_UNAVAIL;
 	}
     }
@@ -1328,6 +1356,9 @@
 	  && (rc = ldapssl_client_init (cfg->ldc_sslpath, NULL)) != LDAP_SUCCESS)
 	{
           debug ("<== do_init (ldapssl_client_init failed with rc = %d)", rc);
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+          _nss_ldap_init_recursion_depth--;
+#endif
 	  return NSS_UNAVAIL;
 	}
       __ssl_initialized = 1;
@@ -1345,6 +1376,9 @@
   if (stat != NSS_SUCCESS)
     {
       debug ("<== do_init (failed to initialize LDAP session)");
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+      _nss_ldap_init_recursion_depth--;
+#endif
       return stat;
     }
 
@@ -1353,6 +1387,9 @@
 
   debug ("<== do_init (initialized session)");
 
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  _nss_ldap_init_recursion_depth--;
+#endif
   return NSS_SUCCESS;
 }
 
@@ -1660,7 +1697,7 @@
 	      ldap_err2string (rc));
       stat = do_map_error (rc);
       do_close ();
-      debug ("<== do_open (failed to bind to DSA");
+      debug ("<== do_open (failed to bind to DSA)");
     }
   else
     {
@@ -2513,6 +2550,19 @@
   NSS_STATUS stat = NSS_UNAVAIL;
   int maxtries;
 
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  if (_nss_ldap_search_recursion_depth > 5)
+    {
+      /* the reasoning here is just a guess, but why else? */
+      syslog (LOG_ERR, "nss_ldap: unable to connect to DSA without "
+	      "information which may need to be retrieved from the DSA");
+      debug ("<=> do_with_reconnect: recursed too far, failing");
+      return NSS_NOTFOUND;
+    }
+
+  _nss_ldap_search_recursion_depth++;
+#endif
+
   debug ("==> do_with_reconnect");
 
   /* caller must successfully call do_init() first */
@@ -2621,6 +2671,11 @@
     }
 
   debug ("<== do_with_reconnect");
+
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  _nss_ldap_search_recursion_depth--;
+#endif
+
   return stat;
 }
 




More information about the fedora-extras-commits mailing list