From cd1fe572f5a5baf2f67e8cdba840135fdb9d3060 Mon Sep 17 00:00:00 2001 From: markj Date: Fri, 24 Oct 2014 20:29:14 +0000 Subject: 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 --- lib/libc/net/nsdispatch.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'lib/libc') 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); } -- cgit v1.1