From 4893970472bd815b8dbb6f6058dd26358700110e Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Tue, 11 Jun 2013 05:33:10 -0400 Subject: [PATCH] Guard one-time initialization with memory barriers Signed-off-by: Anders Kaseorg --- nonlocal-group.c | 6 +++++- nonlocal-passwd.c | 6 +++++- nonlocal-shadow.c | 6 +++++- walk_nss.h | 16 ++++++++++------ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/nonlocal-group.c b/nonlocal-group.c index b4a72d1..9bbe156 100644 --- a/nonlocal-group.c +++ b/nonlocal-group.c @@ -171,6 +171,7 @@ get_local_group(const char *name, struct group *grp, char **buffer, int *errnop) return status; } +static bool grent_initialized = false; static service_user *grent_startp, *grent_nip; static void *grent_fct_start; static union { @@ -195,9 +196,12 @@ _nss_nonlocal_setgrent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (grent_fct_start == NULL) + if (!grent_initialized) { __nss_group_nonlocal_lookup(&grent_startp, grent_fct_name, &grent_fct_start); + __sync_synchronize(); + grent_initialized = true; + } grent_nip = grent_startp; grent_fct.ptr = grent_fct_start; return NSS_STATUS_SUCCESS; diff --git a/nonlocal-passwd.c b/nonlocal-passwd.c index b9a14b5..f8e7f96 100644 --- a/nonlocal-passwd.c +++ b/nonlocal-passwd.c @@ -162,6 +162,7 @@ get_nonlocal_passwd(const char *name, struct passwd *pwd, char **buffer, } +static bool pwent_initialized = false; static service_user *pwent_startp, *pwent_nip; static void *pwent_fct_start; static union { @@ -186,9 +187,12 @@ _nss_nonlocal_setpwent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (pwent_fct_start == NULL) + if (!pwent_initialized) { __nss_passwd_nonlocal_lookup(&pwent_startp, pwent_fct_name, &pwent_fct_start); + __sync_synchronize(); + pwent_initialized = true; + } pwent_nip = pwent_startp; pwent_fct.ptr = pwent_fct_start; return NSS_STATUS_SUCCESS; diff --git a/nonlocal-shadow.c b/nonlocal-shadow.c index bfc201c..98142e1 100644 --- a/nonlocal-shadow.c +++ b/nonlocal-shadow.c @@ -58,6 +58,7 @@ __nss_shadow_nonlocal_lookup(service_user **ni, const char *fct_name, } +static bool spent_initialized = false; static service_user *spent_startp, *spent_nip; static void *spent_fct_start; static union { @@ -82,9 +83,12 @@ _nss_nonlocal_setspent(int stayopen) if (status != NSS_STATUS_SUCCESS) return status; - if (spent_fct_start == NULL) + if (!spent_initialized) { __nss_shadow_nonlocal_lookup(&spent_startp, spent_fct_name, &spent_fct_start); + __sync_synchronize(); + spent_initialized = true; + } spent_nip = spent_startp; spent_fct.ptr = spent_fct_start; return NSS_STATUS_SUCCESS; diff --git a/walk_nss.h b/walk_nss.h index 93af177..78d3575 100644 --- a/walk_nss.h +++ b/walk_nss.h @@ -24,8 +24,9 @@ */ { - static service_user *startp = NULL; - static void *fct_start = NULL; + static bool initialized = false; + static service_user *startp; + static void *fct_start; service_user *nip; union { @@ -34,10 +35,13 @@ } fct; int old_errno = errno; - if (fct_start == NULL && - w.lookup(&startp, w.fct_name, &fct_start) != 0) { - *w.status = NSS_STATUS_UNAVAIL; - goto walk_nss_out; + if (!initialized) { + if (w.lookup(&startp, w.fct_name, &fct_start) != 0) { + *w.status = NSS_STATUS_UNAVAIL; + goto walk_nss_out; + } + __sync_synchronize(); + initialized = true; } nip = startp; -- 2.44.0