From: Nicolas Williams Date: Wed, 12 Sep 2012 16:36:54 +0000 (-0500) Subject: Fix lock inconsistency in ctx_unlock() X-Git-Tag: krb5-1.11-alpha1~180 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=29ee39baa919361ae08e26caab896890d5cb3eb4;p=thirdparty%2Fkrb5.git Fix lock inconsistency in ctx_unlock() 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. Additionally, we don't really need or want to use non-blocking locks, and we certainly don't want to sleep(1) in krb5kdc (possibly several times, as there was a loop over this) when either of the principal or policy DB is locked. Some callers still request non-blocking locks, and ctx_lock() still honors this. ticket: 7360 (new) --- diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c index 87b6c182b8..62fbef748b 100644 --- a/src/plugins/kdb/db2/kdb_db2.c +++ b/src/plugins/kdb/db2/kdb_db2.c @@ -383,12 +383,10 @@ done: static krb5_error_code ctx_unlock(krb5_context context, krb5_db2_context *dbc) { - krb5_error_code retval; + krb5_error_code retval, retval2; DB *db; retval = osa_adb_release_lock(dbc->policy_db); - if (retval) - return retval; if (!dbc->db_locks_held) /* lock already unlocked */ return KRB5_KDB_NOTLOCKED; @@ -399,9 +397,15 @@ ctx_unlock(krb5_context context, krb5_db2_context *dbc) dbc->db = NULL; dbc->db_lock_mode = 0; - retval = krb5_lock_file(context, dbc->db_lf_file, + retval2 = krb5_lock_file(context, dbc->db_lf_file, KRB5_LOCKMODE_UNLOCK); + if (retval2) + return retval2; } + + /* We may be unlocking because osa_adb_get_lock() failed. */ + if (retval == OSA_ADB_NOTLOCKED) + return 0; return retval; }