From 4a179d973b470edf8714155657b6ff205f798cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Aug 2017 10:18:40 +0300 Subject: [PATCH] MXS-1354: Add missing locking to the Users class The Users class now performs locking when a method is called. This will prevent concurrent access to the internal map of users. Added missing const versions of SpinLockGuard. --- include/maxscale/spinlock.hh | 12 ++++++------ server/core/users.cc | 12 +++++++++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/maxscale/spinlock.hh b/include/maxscale/spinlock.hh index 4b0fa511d..dc1bfff21 100644 --- a/include/maxscale/spinlock.hh +++ b/include/maxscale/spinlock.hh @@ -46,7 +46,7 @@ public: /** * Acquires the spinlock. */ - void acquire() + void acquire() const { spinlock_acquire(&m_lock); } @@ -54,7 +54,7 @@ public: /** * Releases the spinlock. */ - void release() + void release() const { spinlock_release(&m_lock); } @@ -64,7 +64,7 @@ private: SpinLock& operator = (const SpinLock&) /* = delete */; private: - SPINLOCK m_lock; + mutable SPINLOCK m_lock; }; /** @@ -85,7 +85,7 @@ public: * * @param lock The spinlock to lock. */ - SpinLockGuard(SPINLOCK& lock) + SpinLockGuard(const SPINLOCK& lock) : m_lock(lock) { spinlock_acquire(&m_lock); @@ -96,7 +96,7 @@ public: * * @param lock The spinlock to lock. */ - SpinLockGuard(SpinLock& lock) + SpinLockGuard(const SpinLock& lock) : m_lock(lock.m_lock) { spinlock_acquire(&m_lock); @@ -115,7 +115,7 @@ private: SpinLockGuard(const SpinLockGuard&) /* = delete */; SpinLockGuard& operator = (const SpinLockGuard&) /* = delete */; - SPINLOCK& m_lock; + const SPINLOCK& m_lock; }; } diff --git a/server/core/users.cc b/server/core/users.cc index bc4c1e2b9..f133ceb32 100644 --- a/server/core/users.cc +++ b/server/core/users.cc @@ -19,6 +19,7 @@ #include #include +#include namespace { @@ -60,11 +61,13 @@ public: bool add(std::string user, std::string password) { + mxs::SpinLockGuard guard(m_lock); return m_data.insert(std::make_pair(user, UserInfo(password))).second; } bool remove(std::string user) { + mxs::SpinLockGuard guard(m_lock); bool rval = false; if (get(user)) @@ -78,6 +81,7 @@ public: bool get(std::string user, UserInfo* output = NULL) const { + mxs::SpinLockGuard guard(m_lock); UserMap::const_iterator it = m_data.find(user); bool rval = false; @@ -96,6 +100,7 @@ public: bool check_permissions(std::string user, permission_type perm) const { + mxs::SpinLockGuard guard(m_lock); UserMap::const_iterator it = m_data.find(user); bool rval = false; @@ -109,6 +114,7 @@ public: bool set_permissions(std::string user, permission_type perm) { + mxs::SpinLockGuard guard(m_lock); UserMap::iterator it = m_data.find(user); bool rval = false; @@ -123,6 +129,7 @@ public: json_t* diagnostic_json() const { + mxs::SpinLockGuard guard(m_lock); json_t* rval = json_array(); for (UserMap::const_iterator it = m_data.begin(); it != m_data.end(); it++) @@ -135,6 +142,7 @@ public: void diagnostic(DCB* dcb) const { + mxs::SpinLockGuard guard(m_lock); if (m_data.size()) { const char *sep = ""; @@ -150,11 +158,13 @@ public: bool empty() const { + mxs::SpinLockGuard guard(m_lock); return m_data.size() > 0; } private: - UserMap m_data; + mxs::SpinLock m_lock; + UserMap m_data; }; }