Skip to content

Commit 979cd4e

Browse files
author
Teddy Reed
authored
[Fix #3831] Apply per-DB instance attach locking (#3862)
1 parent 4375495 commit 979cd4e

5 files changed

Lines changed: 21 additions & 7 deletions

File tree

osquery/devtools/shell.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,8 @@ static int shell_exec(
790790
}
791791

792792
while (zSql[0] && (SQLITE_OK == rc)) {
793+
auto lock(dbc->attachLock());
794+
793795
/* A lock for attaching virtual tables, but also the SQL object states. */
794796
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
795797
if (SQLITE_OK != rc) {

osquery/sql/sqlite_util.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void SQLiteSQLPlugin::detach(const std::string& name) {
203203
if (!dbc->isPrimary()) {
204204
return;
205205
}
206-
detachTableInternal(name, dbc->db());
206+
detachTableInternal(name, dbc);
207207
}
208208

209209
SQLiteDBInstance::SQLiteDBInstance(sqlite3*& db, Mutex& mtx)
@@ -251,6 +251,10 @@ bool SQLiteDBInstance::useCache() const {
251251
return use_cache_;
252252
}
253253

254+
WriteLock SQLiteDBInstance::attachLock() const {
255+
return WriteLock(attach_mutex_);
256+
}
257+
254258
void SQLiteDBInstance::addAffectedTable(VirtualTableContent* table) {
255259
// An xFilter/scan was requested for this virtual table.
256260
affected_tables_.insert(std::make_pair(table->name, table));

osquery/sql/sqlite_util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class SQLiteDBInstance : private boost::noncopyable {
7777
/// Check if the query requested use of the warm query cache.
7878
bool useCache() const;
7979

80+
/// Lock the database for attaching virtual tables.
81+
WriteLock attachLock() const;
82+
8083
private:
8184
/// Handle the primary/forwarding requests for table attribute accesses.
8285
TableAttributes getAttributes() const;
@@ -102,6 +105,9 @@ class SQLiteDBInstance : private boost::noncopyable {
102105
/// An attempted unique lock on the manager's primary database access mutex.
103106
WriteLock lock_;
104107

108+
/// Attaching can occur async from the registry APIs.
109+
mutable Mutex attach_mutex_;
110+
105111
/// Vector of tables that need their constraints cleared after execution.
106112
std::map<std::string, VirtualTableContent*> affected_tables_;
107113

osquery/sql/virtual_table.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ Status attachTableInternal(const std::string& name,
624624

625625
// Note, if the clientData API is used then this will save a registry call
626626
// within xCreate.
627-
RecursiveLock lock(kAttachMutex);
627+
auto lock(instance->attachLock());
628628
int rc = sqlite3_create_module(
629629
instance->db(), name.c_str(), &module, (void*)&(*instance));
630630
if (rc == SQLITE_OK || rc == SQLITE_MISUSE) {
@@ -637,10 +637,11 @@ Status attachTableInternal(const std::string& name,
637637
return Status(rc, getStringForSQLiteReturnCode(rc));
638638
}
639639

640-
Status detachTableInternal(const std::string& name, sqlite3* db) {
641-
RecursiveLock lock(kAttachMutex);
640+
Status detachTableInternal(const std::string& name,
641+
const SQLiteDBInstanceRef& instance) {
642+
auto lock(instance->attachLock());
642643
auto format = "DROP TABLE IF EXISTS temp." + name;
643-
int rc = sqlite3_exec(db, format.c_str(), nullptr, nullptr, 0);
644+
int rc = sqlite3_exec(instance->db(), format.c_str(), nullptr, nullptr, 0);
644645
if (rc != SQLITE_OK) {
645646
LOG(ERROR) << "Error detaching table: " << name << " (" << rc << ")";
646647
}
@@ -655,7 +656,7 @@ Status attachFunctionInternal(
655656
// Hold the manager connection instance again in callbacks.
656657
auto dbc = SQLiteDBManager::get();
657658
// Add some shell-specific functions to the instance.
658-
RecursiveLock lock(kAttachMutex);
659+
auto lock(dbc->attachLock());
659660
int rc = sqlite3_create_function(
660661
dbc->db(),
661662
name.c_str(),

osquery/sql/virtual_table.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ Status attachTableInternal(const std::string& name,
8484
const SQLiteDBInstanceRef& instance);
8585

8686
/// Detach (drop) a table.
87-
Status detachTableInternal(const std::string& name, sqlite3* db);
87+
Status detachTableInternal(const std::string& name,
88+
const SQLiteDBInstanceRef& instance);
8889

8990
Status attachFunctionInternal(
9091
const std::string& name,

0 commit comments

Comments
 (0)