From 32707fb501765a99cd17bb0ad09d6162c2dbf596 Mon Sep 17 00:00:00 2001 From: Russell Hancox Date: Wed, 20 May 2015 11:13:19 -0400 Subject: [PATCH] santa-driver: Fix rare panic in CacheCheck where lock upgrade fails. lck_rw_lock_shared_to_exclusive can return false if a previous reader upgraded. The result is the lock being unlocked and the panic is caused when unlocking a lock that isn't locked. --- Source/santa-driver/SantaDecisionManager.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/santa-driver/SantaDecisionManager.cc b/Source/santa-driver/SantaDecisionManager.cc index c9222b7c3..d9d639b43 100644 --- a/Source/santa-driver/SantaDecisionManager.cc +++ b/Source/santa-driver/SantaDecisionManager.cc @@ -185,7 +185,12 @@ void SantaDecisionManager::CacheCheck(const char *identifier) { lck_rw_lock_shared(cached_decisions_lock_); bool shouldInvalidate = (cached_decisions_->getObject(identifier) != NULL); if (shouldInvalidate) { - lck_rw_lock_shared_to_exclusive(cached_decisions_lock_); + if (!lck_rw_lock_shared_to_exclusive(cached_decisions_lock_)) { + // shared_to_exclusive will return false if a previous reader upgraded + // and if that happens the lock will have been unlocked. If that happens, + // which is rare, relock exclusively. + lck_rw_lock_exclusive(cached_decisions_lock_); + } cached_decisions_->removeObject(identifier); lck_rw_unlock_exclusive(cached_decisions_lock_); } else { @@ -282,7 +287,7 @@ santa_action_t SantaDecisionManager::GetFromDaemon( CacheCheck(vnode_id_str); return ACTION_ERROR; } - + return return_action; }