Fix race condition in alarm lock processing noticed by Richard Sharpe <realrichardsha...
authorJeremy Allison <jra@samba.org>
Thu, 8 Jan 2009 18:36:10 +0000 (10:36 -0800)
committerJeremy Allison <jra@samba.org>
Thu, 8 Jan 2009 18:36:10 +0000 (10:36 -0800)
"It seems to me that if the lock is already held by another process when we
enter this code, there is a race between the timeout and the granting. If
the lock is subsequently granted, the process releasing the lock will signal
the wait variable (or whatever) and our process will be scheduled. However,
if the timeout occurs before we are scheduled, the timeout will be delivered
first.

We will have the lock but will forget we have the lock, and never release
it."
Jeremy.

source3/lib/util_tdb.c

index bb568bc22e9b8837563ca2a034751e4b52c0fbd5..8ceaa4667040817b85d95b44401996c588f5cbdd 100644 (file)
@@ -64,7 +64,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
                alarm(0);
                tdb_setalarm_sigptr(tdb, NULL);
                CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
-               if (gotalarm) {
+               if (gotalarm && (ret == -1)) {
                        DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
                                timeout, key.dptr, tdb_name(tdb)));
                        /* TODO: If we time out waiting for a lock, it might