]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix lock inconsistency in krb5_db2_unlock()
authorTom Yu <tlyu@mit.edu>
Wed, 3 Jul 2013 22:16:38 +0000 (18:16 -0400)
committerTom Yu <tlyu@mit.edu>
Fri, 5 Jul 2013 23:29:53 +0000 (19:29 -0400)
[ text below refers to new function names in krb5-1.10+ ]

The lock inconsistency fixed here is quite possibly the same as
described in https://bugzilla.redhat.com/show_bug.cgi?id=586032 .

The problem is that ctx_unlock() fails to unlock the principal DB if
it fails to unlock the policy DB, and this happens when ctx_lock()
fails to lock the policy DB (likely because the caller is racing
against a kdb5_util load, which will be using a "permanent" lock,
meaning that the lock file will be unlinked after acquiring the
lock).  The fix is to perform both unlock operations *then* handle
any errors that either or both might have returned.

(back ported from commit 29ee39baa919361ae08e26caab896890d5cb3eb4)

ticket: 7674 (new)
version_fixed: 1.9.6
status: resolved

src/plugins/kdb/db2/kdb_db2.c

index 59660da1ef6ad5ce00b2c202b1cfbd527647cc5a..210afff00a118da12199614f9ba2fbf4e139d163 100644 (file)
@@ -620,16 +620,14 @@ krb5_db2_unlock(krb5_context context)
 {
     krb5_db2_context *db_ctx;
     DB     *db;
-    krb5_error_code retval;
+    krb5_error_code retval, retval2;
 
     if (!k5db2_inited(context))
         return KRB5_KDB_DBNOTINITED;
 
     db_ctx = context->dal_handle->db_context;
 
-    if ((retval = osa_adb_release_lock(db_ctx->policy_db))) {
-        return retval;
-    }
+    retval = osa_adb_release_lock(db_ctx->policy_db);
 
     if (!db_ctx->db_locks_held) /* lock already unlocked */
         return KRB5_KDB_NOTLOCKED;
@@ -637,13 +635,18 @@ krb5_db2_unlock(krb5_context context)
     if (--(db_ctx->db_locks_held) == 0) {
         (*db->close) (db);
         db_ctx->db = NULL;
-
-        retval = krb5_lock_file(context, db_ctx->db_lf_file,
-                                KRB5_LOCKMODE_UNLOCK);
         db_ctx->db_lock_mode = 0;
-        return (retval);
+
+        retval2 = krb5_lock_file(context, db_ctx->db_lf_file,
+                                 KRB5_LOCKMODE_UNLOCK);
+        if (retval2)
+            return retval2;
     }
-    return 0;
+
+    /* We may be unlocking because osa_adb_get_lock() failed. */
+    if (retval == OSA_ADB_NOTLOCKED)
+        return 0;
+    return retval;
 }
 
 /* Create the database, assuming it's not there. */