Fix ASan logger shutdown use-after-free

This commit is contained in:
oltolm 2026-04-09 23:51:34 +02:00 committed by Elad
parent 110c786d80
commit 7168cd566a
3 changed files with 23 additions and 2 deletions

View File

@ -656,7 +656,7 @@ int run_rpcs3(int argc, char** argv)
// Initialize thread pool finalizer (on first use) // Initialize thread pool finalizer (on first use)
static_cast<void>(named_thread("", [](int) {})); static_cast<void>(named_thread("", [](int) {}));
static std::unique_ptr<logs::listener> log_file; std::unique_ptr<logs::listener> log_file;
{ {
// Check free space // Check free space
fs::device_stat stats{}; fs::device_stat stats{};
@ -669,9 +669,17 @@ int run_rpcs3(int argc, char** argv)
log_file = logs::make_file_listener(log_name, stats.avail_free / 4); log_file = logs::make_file_listener(log_name, stats.avail_free / 4);
} }
static std::unique_ptr<fatal_error_listener> fatal_listener = std::make_unique<fatal_error_listener>(); auto fatal_listener = std::make_unique<fatal_error_listener>();
logs::listener::add(fatal_listener.get()); logs::listener::add(fatal_listener.get());
struct log_listener_shutdown_guard
{
~log_listener_shutdown_guard()
{
logs::listener::shutdown_all();
}
} log_listener_shutdown;
{ {
// Write RPCS3 version // Write RPCS3 version
logs::stored_message ver{sys_log.always()}; logs::stored_message ver{sys_log.always()};

View File

@ -372,6 +372,16 @@ void logs::listener::sync_all()
} }
} }
void logs::listener::shutdown_all()
{
std::lock_guard lock(g_mutex);
for (listener* lis = get_logger()->m_next.exchange(nullptr); lis;)
{
lis = lis->m_next.exchange(nullptr);
}
}
void logs::listener::close_all_prematurely() void logs::listener::close_all_prematurely()
{ {
for (listener* lis = get_logger(); lis; lis = lis->m_next) for (listener* lis = get_logger(); lis; lis = lis->m_next)

View File

@ -98,6 +98,9 @@ namespace logs
// Flush log to disk // Flush log to disk
static void sync_all(); static void sync_all();
// Detach all listeners before controlled shutdown tears them down.
static void shutdown_all();
// Close file handle after flushing to disk (hazardous) // Close file handle after flushing to disk (hazardous)
static void close_all_prematurely(); static void close_all_prematurely();
}; };