>From 9a9834cb949abeebc6308cd6d2e92704cbd52af1 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 13 Aug 2012 15:30:39 +0200 Subject: [PATCH] Use PTHREAD_MUTEX_ROBUST to avoid deadlock in the client --- Makefile.am | 8 +++++- src/sss_client/common.c | 68 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index e89938ecaff3d40faa50ffafcf88ea3dda1bacca..e218b440628d08fa743eeba290b63d6dc9a14a81 100644 --- a/Makefile.am +++ b/Makefile.am @@ -738,6 +738,7 @@ sss_sudo_cli_SOURCES = \ src/sss_client/common.c \ src/sss_client/sudo_testcli/sudo_testcli.c sss_sudo_cli_CFLAGS = $(AM_CFLAGS) +sss_sudo_cli_LDFLAGS = -lpthread sss_sudo_cli_LDADD = \ libsss_sudo.la endif @@ -1121,7 +1122,7 @@ autofs_test_client_SOURCES = src/sss_client/autofs/autofs_test_client.c \ src/sss_client/autofs/sss_autofs.c \ src/sss_client/common.c autofs_test_client_CFLAGS = $(AM_CFLAGS) -autofs_test_client_LDFLAGS = -lpopt +autofs_test_client_LDFLAGS = -lpopt -lpthread endif #################### @@ -1143,6 +1144,7 @@ libnss_sss_la_SOURCES = \ src/sss_client/nss_mc_group.c \ src/sss_client/nss_mc.h libnss_sss_la_LDFLAGS = \ + -lpthread \ -module \ -version-info 2:0:0 \ -Wl,--version-script,$(srcdir)/src/sss_client/sss_nss.exports @@ -1156,6 +1158,7 @@ pam_sss_la_SOURCES = \ src/sss_client/sss_pam_macros.h pam_sss_la_LDFLAGS = \ + -lpthread \ -lpam \ -module \ -avoid-version \ @@ -1171,6 +1174,7 @@ libsss_sudo_la_SOURCES = \ src/sss_client/sudo/sss_sudo.h \ src/sss_client/sudo/sss_sudo_private.h libsss_sudo_la_LDFLAGS = \ + -lpthread \ -Wl,--version-script,$(srcdir)/src/sss_client/sss_sudo.exports \ -version-info 2:0:1 @@ -1190,6 +1194,7 @@ libsss_autofs_la_SOURCES = \ src/sss_client/autofs/sss_autofs_private.h libsss_autofs_la_LDFLAGS = \ + -lpthread \ -module \ -avoid-version \ -Wl,--version-script,$(srcdir)/src/sss_client/autofs/sss_autofs.exports @@ -1508,6 +1513,7 @@ sssd_pac_plugin_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) sssd_pac_plugin_la_LDFLAGS = \ + -lpthread \ -lkrb5 \ -avoid-version \ -module diff --git a/src/sss_client/common.c b/src/sss_client/common.c index 59eae3b1fe4101383de96f680458467a962c2248..4d1f33f14f6dd7a9f295c10b974d7858b38fcaf3 100644 --- a/src/sss_client/common.c +++ b/src/sss_client/common.c @@ -976,24 +976,80 @@ errno_t sss_strnlen(const char *str, size_t maxlen, size_t *len) } #if HAVE_PTHREAD -static pthread_mutex_t sss_nss_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t sss_pam_mutex = PTHREAD_MUTEX_INITIALIZER; +typedef void (*sss_mutex_init)(void); +struct sss_mutex { + pthread_mutexattr_t attr; + pthread_mutex_t mtx; + + pthread_once_t once; + sss_mutex_init init; +}; + +static void sss_nss_mt_init(void); +static void sss_pam_mt_init(void); + +static struct sss_mutex nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, + .once = PTHREAD_ONCE_INIT, + .init = sss_nss_mt_init }; + +static struct sss_mutex pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, + .once = PTHREAD_ONCE_INIT, + .init = sss_pam_mt_init }; + +/* Generic mutex init, lock, unlock functions */ +void sss_mt_init(struct sss_mutex *m) +{ + if (pthread_mutexattr_init(&m->attr) != 0) { + return; + } + if (pthread_mutexattr_setrobust(&m->attr, PTHREAD_MUTEX_ROBUST) != 0) { + return; + } + if (pthread_mutex_init(&m->mtx, &m->attr) != 0) { + return; + } +} + +void sss_mt_lock(struct sss_mutex *m) +{ + pthread_once(&m->once, m->init); + if (pthread_mutex_lock(&m->mtx) == EOWNERDEAD) { + pthread_mutex_consistent(&m->mtx); + } +} + +void sss_mt_unlock(struct sss_mutex *m) +{ + pthread_mutex_unlock(&m->mtx); +} + +/* NSS mutex wrappers */ +static void sss_nss_mt_init(void) +{ + sss_mt_init(&nss_mtx); +} void sss_nss_lock(void) { - pthread_mutex_lock(&sss_nss_mutex); + sss_mt_lock(&nss_mtx); } void sss_nss_unlock(void) { - pthread_mutex_unlock(&sss_nss_mutex); + sss_mt_unlock(&nss_mtx); +} + +/* NSS mutex wrappers */ +static void sss_pam_mt_init(void) +{ + sss_mt_init(&pam_mtx); } void sss_pam_lock(void) { - pthread_mutex_lock(&sss_pam_mutex); + sss_mt_lock(&pam_mtx); } void sss_pam_unlock(void) { - pthread_mutex_unlock(&sss_pam_mutex); + sss_mt_unlock(&pam_mtx); } #else -- 1.7.11.2