nss_ldap broken

Jacques A. Vidrine nectar at FreeBSD.org
Fri Mar 26 13:20:05 PST 2004


On Fri, Mar 26, 2004 at 12:40:20PM -0800, Sean McNeil wrote:
> Interesting!!! Not what I had thought was going on.  I compiled libc
> with symbols and I get this:
> 
> #0  0x28214800 in ?? ()
> #1  0x2816be35 in nss_atexit () at
> /usr/src/lib/libc/net/nsdispatch.c:518
> #2  0x2818e9db in __cxa_finalize (dso=0x0)
>     at /usr/src/lib/libc/stdlib/atexit.c:184
> #3  0x2818e6fc in exit (status=672827136) at
> /usr/src/lib/libc/stdlib/exit.c:69
> #4  0x08049b68 in free () at /usr/src/lib/libc/stdlib/malloc.c:1153
> #5  0x08049279 in free () at /usr/src/lib/libc/stdlib/malloc.c:1153
> 
> So even though the write lock didn't cause a crash the unlock did.

That's quite curious!  It makes me suspect that somewhere in one
of ns_dbt_free or ns_mod_free, the lock is getting trashed.


On Fri, Mar 26, 2004 at 01:00:40PM -0800, Sean McNeil wrote:
> This appears to be an issue with any external nss_*.so.1 module that
> uses pthread.

Hmm, perhaps so.  One thing that is happening between the wrlock and
unlock that we're looking at, is that NSS modules will be dlclosed(),
and thus all libraries in the dependency DAG will also be unloaded.


> It looks to me it is about the following:
> 
> /*
>  * Cleanup
>  */
> static void
> nss_atexit(void)
> {
> 	(void)_pthread_rwlock_wrlock(&nss_lock);
> 	VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap),
> 	    (vector_free_elem)ns_dbt_free);
> 	VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod),
> 	    (vector_free_elem)ns_mod_free);
> 	(void)_pthread_rwlock_unlock(&nss_lock);
> }
> 
> In my case, the nss_ldap.so.1 module was loaded which pulls in
> libpthread.

Hmm, but RTLD_LOCAL is being used here, so symbols in nss_ldap.so.1's
dependency DAG shouldn't become visible for the rest of the processes
objects... hmm

> I'm not sure how this works without a libpthred, but it
> would appear that unless libpthread.so is loaded everything is OK.  But
> now, it has been loaded and the rwlock_wrlock() works, but then it has
> been unloaded before rwlock_unlock() gets called.
> 
> Would using
> 
> #include <reentrant.h>
> rwlock_wrlock()
> rwlock_unlock()
> 
> macros fix this?

AFAIK, those macros are only an optimization--- they just check a
global variable to see if we're threaded or not.


Good detective work.  I must split for now, but maybe some RTLD
and thread gurus could glance at what we're discussing here and
let us know if anything smells funny...  Certainly, I would not be
surprised if there are side effects I have not calculated due to
loading/unloading libpthread...

Cheers,
-- 
Jacques Vidrine / nectar at celabo.org / jvidrine at verio.net / nectar at freebsd.org


More information about the freebsd-current mailing list