From 1f680bfd1014467347cb47cded9a1e05fa354ccf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Feb 2010 14:24:08 -0800 Subject: [PATCH] lockdep: fix use after free; avoid register in unlocked() path --- src/common/Mutex.h | 8 ++++---- src/common/RWLock.h | 2 +- src/common/Spinlock.h | 8 ++++---- src/common/lockdep.cc | 10 +++++++--- src/common/lockdep.h | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/common/Mutex.h b/src/common/Mutex.h index f0e8759cb3849..7a6d67a8b60a9 100755 --- a/src/common/Mutex.h +++ b/src/common/Mutex.h @@ -47,14 +47,14 @@ private: void _locked() { // just locked id = lockdep_locked(name, id, backtrace); } - void _unlocked() { // just unlocked - id = lockdep_unlocked(name, id); + void _will_unlock() { // about to unlock + id = lockdep_will_unlock(name, id); } #else void _register() {} void _will_lock() {} // about to lock void _locked() {} // just locked - void _unlocked() {} // just unlocked + void _will_unlock() {} // about to unlock #endif public: @@ -100,9 +100,9 @@ public: void Unlock() { assert(nlock > 0); --nlock; + if (lockdep && g_lockdep) _will_unlock(); int r = pthread_mutex_unlock(&_m); assert(r == 0); - if (lockdep && g_lockdep) _unlocked(); } friend class Cond; diff --git a/src/common/RWLock.h b/src/common/RWLock.h index e1065e2bba97c..7db72f07e3b8d 100644 --- a/src/common/RWLock.h +++ b/src/common/RWLock.h @@ -39,7 +39,7 @@ class RWLock } void unlock() { - if (g_lockdep) id = lockdep_unlocked(name, id); + if (g_lockdep) id = lockdep_will_unlock(name, id); pthread_rwlock_unlock(&L); } diff --git a/src/common/Spinlock.h b/src/common/Spinlock.h index c0bba996a336a..95598a3909120 100644 --- a/src/common/Spinlock.h +++ b/src/common/Spinlock.h @@ -45,14 +45,14 @@ private: void _locked() { // just locked id = lockdep_locked(name, id, backtrace); } - void _unlocked() { // just unlocked - id = lockdep_unlocked(name, id); + void _will_unlock() { // about to unlock + id = lockdep_will_unlock(name, id); } #else void _register() {} void _will_lock() {} // about to lock void _locked() {} // just locked - void _unlocked() {} // just unlocked + void _will_unlock() {} // about to unlock #endif public: @@ -90,9 +90,9 @@ public: void unlock() { assert(nlock > 0); --nlock; + if (lockdep && g_lockdep) _will_unlock(); int r = pthread_spin_unlock(&_s); assert(r == 0); - if (lockdep && g_lockdep) _unlocked(); } public: diff --git a/src/common/lockdep.cc b/src/common/lockdep.cc index 8b37dc18dd8ef..ed5162bdbfc99 100644 --- a/src/common/lockdep.cc +++ b/src/common/lockdep.cc @@ -210,14 +210,18 @@ int lockdep_locked(const char *name, int id, bool force_backtrace) return id; } -int lockdep_unlocked(const char *name, int id) +int lockdep_will_unlock(const char *name, int id) { pthread_t p = pthread_self(); - if (id < 0) id = lockdep_register(name); + if (id < 0) { + //id = lockdep_register(name); + assert(id == -1); + return id; + } pthread_mutex_lock(&lockdep_mutex); - dout(20) << "_unlocked " << name << std::endl; + dout(20) << "_will_unlock " << name << std::endl; // don't assert.. lockdep may be enabled at any point in time //assert(held.count(p)); diff --git a/src/common/lockdep.h b/src/common/lockdep.h index f1303773a4fc9..78784bcbbe04d 100644 --- a/src/common/lockdep.h +++ b/src/common/lockdep.h @@ -6,7 +6,7 @@ extern int g_lockdep; extern int lockdep_register(const char *n); extern int lockdep_will_lock(const char *n, int id); extern int lockdep_locked(const char *n, int id, bool force_backtrace=false); -extern int lockdep_unlocked(const char *n, int id); +extern int lockdep_will_unlock(const char *n, int id); extern int lockdep_dump_locks(); #endif -- 2.39.5