Race condition in tdb_runtime_check_for_robust_mutexes()

Ralph Boehme rb at sernet.de
Fri Mar 25 05:10:24 UTC 2016


On Thu, Mar 24, 2016 at 11:34:11PM +0200, Uri Simchoni wrote:
> On 03/24/2016 04:57 PM, Ralph Boehme wrote:
> > Something like the attached patch. This can probably be enhanced by
> > using pselect with a timeout and a signal mask to block/unblock
> > SIGCHLD instead of sleep.
> > 
> ENOPATCH?

gna, attached.

-Ralph

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de,mailto:kontakt@sernet.de
-------------- next part --------------
From 091cfad07a7693cb88f76e46f576fd39978bdc6f Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Thu, 24 Mar 2016 15:49:13 +0100
Subject: [PATCH] WIP: only call waitpid() in the signal handler

---
 lib/tdb/common/mutex.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/lib/tdb/common/mutex.c b/lib/tdb/common/mutex.c
index fae43d4..9556238 100644
--- a/lib/tdb/common/mutex.c
+++ b/lib/tdb/common/mutex.c
@@ -723,9 +723,6 @@ static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int),
 	memset(&act, '\0', sizeof(act));
 
 	act.sa_handler = handler;
-#ifdef SA_RESTART
-	act.sa_flags = SA_RESTART;
-#endif
 	sigemptyset(&act.sa_mask);
 	sigaddset(&act.sa_mask, SIGCHLD);
 	sigaction(SIGCHLD, &act, &oldact);
@@ -884,17 +881,11 @@ _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void)
 	}
 
 	while (tdb_robust_mutex_pid > 0) {
-		pid_t pid;
-
-		errno = 0;
-		pid = waitpid(tdb_robust_mutex_pid, &status, 0);
-		if (pid == tdb_robust_mutex_pid) {
-			tdb_robust_mutex_pid = -1;
-			break;
-		}
-		if (pid == -1 && errno != EINTR) {
-			goto cleanup_child;
-		}
+		/*
+		 * RACE: if the SIGCHLD is delivered now, *before* the
+		 * sleep, we will unneededly sleep for one second.
+		 */
+		sleep(1);
 	}
 	tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL);
 
@@ -927,19 +918,12 @@ _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void)
 
 cleanup_child:
 	while (tdb_robust_mutex_pid > 0) {
-		pid_t pid;
-
+		/*
+		 * RACE: if the SIGCHLD is delivered now, *before* the
+		 * sleep, we will unneededly sleep for one second.
+		 */
 		kill(tdb_robust_mutex_pid, SIGKILL);
-
-		errno = 0;
-		pid = waitpid(tdb_robust_mutex_pid, &status, 0);
-		if (pid == tdb_robust_mutex_pid) {
-			tdb_robust_mutex_pid = -1;
-			break;
-		}
-		if (pid == -1 && errno != EINTR) {
-			break;
-		}
+		sleep();
 	}
 cleanup_sig_child:
 	tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL);
-- 
2.5.0



More information about the samba-technical mailing list