From a8a01bfaaee11c8bf0893b27889bc8d91e4a6159 Mon Sep 17 00:00:00 2001 From: Rachel Date: Wed, 10 Dec 2025 21:15:22 +0800 Subject: [PATCH 1/2] Kernel.Event: fix potential use-after-free in EqueueInternal::ScheduleEvent --- src/core/libraries/kernel/equeue.cpp | 10 +++++++++- src/core/libraries/kernel/equeue.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index 2190f2533..ee9f5600e 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -65,8 +65,16 @@ bool EqueueInternal::ScheduleEvent(u64 id, s16 filter, it->timer->expires_at(it->timer->expiry() + event.timer_interval); } + std::weak_ptr weak_token = m_life_token; + it->timer->async_wait( - [this, event_data = event.event, callback](const boost::system::error_code& ec) { + [this, event_data = event.event, callback, weak_token](const boost::system::error_code& ec) { + + // If the token already expires return to avoid calling to callback with an invalid pointer. + if (weak_token.expired()) { + return; + } + if (ec) { if (ec != boost::system::errc::operation_canceled) { LOG_ERROR(Kernel_Event, "Timer callback error: {}", ec.message()); diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h index e933f80d1..99caad59e 100644 --- a/src/core/libraries/kernel/equeue.h +++ b/src/core/libraries/kernel/equeue.h @@ -180,6 +180,7 @@ private: std::vector m_events; std::condition_variable m_cond; std::unordered_map m_small_timers; + std::shared_ptr m_life_token = std::make_shared(0); }; u64 PS4_SYSV_ABI sceKernelGetEventData(const SceKernelEvent* ev); From 6e3360dcc6987ac25ad4647e3e195afecb0d2c6e Mon Sep 17 00:00:00 2001 From: Rachel Date: Thu, 11 Dec 2025 17:37:33 +0800 Subject: [PATCH 2/2] Kernel.Event: fix style --- src/core/libraries/kernel/equeue.cpp | 33 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index ee9f5600e..237043d40 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -67,25 +67,24 @@ bool EqueueInternal::ScheduleEvent(u64 id, s16 filter, std::weak_ptr weak_token = m_life_token; - it->timer->async_wait( - [this, event_data = event.event, callback, weak_token](const boost::system::error_code& ec) { + it->timer->async_wait([this, event_data = event.event, callback, + weak_token](const boost::system::error_code& ec) { + // If the token already expires return to avoid calling to callback with an invalid pointer. + if (weak_token.expired()) { + return; + } - // If the token already expires return to avoid calling to callback with an invalid pointer. - if (weak_token.expired()) { - return; + if (ec) { + if (ec != boost::system::errc::operation_canceled) { + LOG_ERROR(Kernel_Event, "Timer callback error: {}", ec.message()); + } else { + // Timer was cancelled (removed) before it triggered + LOG_DEBUG(Kernel_Event, "Timer cancelled"); } - - if (ec) { - if (ec != boost::system::errc::operation_canceled) { - LOG_ERROR(Kernel_Event, "Timer callback error: {}", ec.message()); - } else { - // Timer was cancelled (removed) before it triggered - LOG_DEBUG(Kernel_Event, "Timer cancelled"); - } - return; - } - callback(this, event_data); - }); + return; + } + callback(this, event_data); + }); KernelSignalRequest(); return true;