From a18444813b076433258b7e5598765a5b8c91f590 Mon Sep 17 00:00:00 2001 From: Teddy Reed Date: Sat, 26 Mar 2016 21:52:22 -0700 Subject: [PATCH] [Fix #1971] Use recursive locks for config data predicates --- osquery/config/config.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/osquery/config/config.cpp b/osquery/config/config.cpp index b9e52b46..8affe424 100644 --- a/osquery/config/config.cpp +++ b/osquery/config/config.cpp @@ -56,12 +56,17 @@ const std::string kExecutingQuery = "executing_query"; const std::string kFailedQueries = "failed_queries"; // The config may be accessed and updated asynchronously; use mutexes. -Mutex config_schedule_mutex_; -Mutex config_performance_mutex_; -Mutex config_files_mutex_; Mutex config_hash_mutex_; Mutex config_valid_mutex_; +using RecursiveMutex = std::recursive_mutex; +using RecursiveLock = std::lock_guard; + +/// Several config methods require enumeration via predicate lambdas. +RecursiveMutex config_schedule_mutex_; +RecursiveMutex config_files_mutex_; +RecursiveMutex config_performance_mutex_; + using PackRef = std::shared_ptr; /** @@ -218,7 +223,7 @@ Config::Config() void Config::addPack(const std::string& name, const std::string& source, const pt::ptree& tree) { - WriteLock wlock(config_schedule_mutex_); + RecursiveLock wlock(config_schedule_mutex_); try { schedule_->add(std::make_shared(name, source, tree)); if (schedule_->last()->shouldPackExecute()) { @@ -230,19 +235,19 @@ void Config::addPack(const std::string& name, } void Config::removePack(const std::string& pack) { - WriteLock wlock(config_schedule_mutex_); + RecursiveLock wlock(config_schedule_mutex_); return schedule_->remove(pack); } void Config::addFile(const std::string& source, const std::string& category, const std::string& path) { - WriteLock wlock(config_files_mutex_); + RecursiveLock wlock(config_files_mutex_); files_[source][category].push_back(path); } void Config::removeFiles(const std::string& source) { - WriteLock wlock(config_files_mutex_); + RecursiveLock wlock(config_files_mutex_); if (files_.count(source)) { FileCategories().swap(files_[source]); } @@ -251,7 +256,7 @@ void Config::removeFiles(const std::string& source) { void Config::scheduledQueries( std::function predicate) { - WriteLock lock(config_schedule_mutex_); + RecursiveLock lock(config_schedule_mutex_); for (const PackRef& pack : *schedule_) { for (const auto& it : pack->getSchedule()) { std::string name = it.first; @@ -279,7 +284,7 @@ void Config::scheduledQueries( } void Config::packs(std::function predicate) { - WriteLock lock(config_schedule_mutex_); + RecursiveLock lock(config_schedule_mutex_); for (PackRef& pack : schedule_->packs_) { predicate(pack); } @@ -532,7 +537,7 @@ void Config::purge() { return false; }; - WriteLock lock(config_schedule_mutex_); + RecursiveLock lock(config_schedule_mutex_); // Iterate over each result set in the database. for (const auto& saved_query : saved_queries) { if (queryExists(saved_query)) { @@ -585,7 +590,7 @@ void Config::recordQueryPerformance(const std::string& name, size_t size, const Row& r0, const Row& r1) { - WriteLock lock(config_performance_mutex_); + RecursiveLock lock(config_performance_mutex_); if (performance_.count(name) == 0) { performance_[name] = QueryPerformance(); } @@ -643,7 +648,7 @@ void Config::getPerformanceStats( const std::string& name, std::function predicate) { if (performance_.count(name) > 0) { - WriteLock lock(config_performance_mutex_); + RecursiveLock lock(config_performance_mutex_); predicate(performance_.at(name)); } } @@ -688,7 +693,7 @@ const std::shared_ptr Config::getParser( void Config::files( std::function& files)> predicate) { - WriteLock lock(config_files_mutex_); + RecursiveLock lock(config_files_mutex_); for (const auto& it : files_) { for (const auto& category : it.second) { predicate(category.first, category.second);