diff options
author | markj <markj@FreeBSD.org> | 2014-10-24 20:29:14 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2014-10-24 20:29:14 +0000 |
commit | cd1fe572f5a5baf2f67e8cdba840135fdb9d3060 (patch) | |
tree | 2b6bad90298b5f547cf208a750b109e4c8c23ed4 /lib/libc | |
parent | 5dd26e948ded0a684546918d8402bc5beced28fb (diff) | |
download | FreeBSD-src-cd1fe572f5a5baf2f67e8cdba840135fdb9d3060.zip FreeBSD-src-cd1fe572f5a5baf2f67e8cdba840135fdb9d3060.tar.gz |
Eliminate conf_lock and instead rely on the NSS write lock to protect
NSS configuration state.
As a side effect, this fixes a race condition which can occur if multiple
threads call nsdispatch(3) concurrently before nsswitch.conf has been
parsed. Previously, the thread holding conf_lock could cause other threads
to return from nss_configure() before nsswitch.conf had been parsed, forcing
them to fall back to the default sources for their NSS methods.
Reviewed by: jhb
Differential Revision: https://reviews.freebsd.org/D994
MFC after: 1 month
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/net/nsdispatch.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/lib/libc/net/nsdispatch.c b/lib/libc/net/nsdispatch.c index 4fbc9ba..c23315c 100644 --- a/lib/libc/net/nsdispatch.c +++ b/lib/libc/net/nsdispatch.c @@ -329,7 +329,6 @@ _nsdbtdump(const ns_dbt *dbt) static int nss_configure(void) { - static pthread_mutex_t conf_lock = PTHREAD_MUTEX_INITIALIZER; static time_t confmod; struct stat statbuf; int result, isthreaded; @@ -353,13 +352,14 @@ nss_configure(void) if (statbuf.st_mtime <= confmod) return (0); if (isthreaded) { - result = _pthread_mutex_trylock(&conf_lock); - if (result != 0) - return (0); (void)_pthread_rwlock_unlock(&nss_lock); result = _pthread_rwlock_wrlock(&nss_lock); if (result != 0) - goto fin2; + return (result); + if (stat(path, &statbuf) != 0) + goto fin; + if (statbuf.st_mtime <= confmod) + goto fin; } _nsyyin = fopen(path, "re"); if (_nsyyin == NULL) @@ -390,9 +390,6 @@ fin: if (result == 0) result = _pthread_rwlock_rdlock(&nss_lock); } -fin2: - if (isthreaded) - (void)_pthread_mutex_unlock(&conf_lock); return (result); } |