summaryrefslogtreecommitdiff
path: root/src/Main.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-02-20 20:31:08 +0100
committerMax Kellermann <max@musicpd.org>2019-02-20 20:50:28 +0100
commitcc28a7b67fcfe006b49171343eaf37f5862014da (patch)
tree8ec76f4a82e22f688ee83db70cb81b964063d656 /src/Main.cxx
parent8b5c33cecdb1e41b08d8141222f6dba50a836889 (diff)
Main: create Database on stack, move to Instance after Open() succeeded
This fixes use-after-free bug in SimpleDatabase::Close(), accessing the `root` object which was already freed by the `catch` block in Open(). By having the Database on the stack first, we can avoid calling Close() on the failed-to-open Database from Instance's destructor. Closes #482
Diffstat (limited to 'src/Main.cxx')
-rw-r--r--src/Main.cxx24
1 files changed, 12 insertions, 12 deletions
diff --git a/src/Main.cxx b/src/Main.cxx
index 87bda1734..686813c1c 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -185,18 +185,16 @@ InitStorage(const ConfigData &config, EventLoop &event_loop)
static bool
glue_db_init_and_load(const ConfigData &config)
{
- instance->database =
- CreateConfiguredDatabase(config, instance->event_loop,
- instance->io_thread.GetEventLoop(),
- *instance);
- if (instance->database == nullptr)
+ auto db = CreateConfiguredDatabase(config, instance->event_loop,
+ instance->io_thread.GetEventLoop(),
+ *instance);
+ if (!db)
return true;
- if (instance->database->GetPlugin().RequireStorage()) {
+ if (db->GetPlugin().RequireStorage()) {
InitStorage(config, instance->io_thread.GetEventLoop());
if (instance->storage == nullptr) {
- instance->database.reset();
LogDefault(config_domain,
"Found database setting without "
"music_directory - disabling database");
@@ -210,22 +208,24 @@ glue_db_init_and_load(const ConfigData &config)
}
try {
- instance->database->Open();
+ db->Open();
} catch (...) {
std::throw_with_nested(std::runtime_error("Failed to open database plugin"));
}
- auto *db = dynamic_cast<SimpleDatabase *>(instance->database.get());
- if (db == nullptr)
+ instance->database = std::move(db);
+
+ auto *sdb = dynamic_cast<SimpleDatabase *>(instance->database.get());
+ if (sdb == nullptr)
return true;
instance->update = new UpdateService(config,
- instance->event_loop, *db,
+ instance->event_loop, *sdb,
static_cast<CompositeStorage &>(*instance->storage),
*instance);
/* run database update after daemonization? */
- return db->FileExists();
+ return sdb->FileExists();
}
static bool