kern: fix reference leak in KThread::GetThreadFromId callers

This commit is contained in:
Michael Scire 2020-08-15 03:01:43 -07:00 committed by SciresM
parent f77a4fbf98
commit e5d30217d3
2 changed files with 15 additions and 12 deletions

View file

@ -471,8 +471,9 @@ namespace ams::kern {
KScopedLightLock lk(this->lock); KScopedLightLock lk(this->lock);
/* Get the thread from its id. */ /* Get the thread from its id. */
KScopedAutoObject thread = KThread::GetThreadFromId(thread_id); KThread *thread = KThread::GetThreadFromId(thread_id);
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidId()); R_UNLESS(thread != nullptr, svc::ResultInvalidId());
ON_SCOPE_EXIT { thread->Close(); };
/* Verify that the thread is owned by our process. */ /* Verify that the thread is owned by our process. */
R_UNLESS(this->process == thread->GetOwnerProcess(), svc::ResultInvalidId()); R_UNLESS(this->process == thread->GetOwnerProcess(), svc::ResultInvalidId());
@ -482,7 +483,7 @@ namespace ams::kern {
/* Check that the thread is not the current one. */ /* Check that the thread is not the current one. */
/* NOTE: Nintendo does not check this, and thus the following loop will deadlock. */ /* NOTE: Nintendo does not check this, and thus the following loop will deadlock. */
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(), svc::ResultInvalidId()); R_UNLESS(thread != GetCurrentThreadPointer(), svc::ResultInvalidId());
/* Try to get the thread context until the thread isn't current on any core. */ /* Try to get the thread context until the thread isn't current on any core. */
while (true) { while (true) {
@ -495,7 +496,7 @@ namespace ams::kern {
if (thread->GetRawState() != KThread::ThreadState_Runnable) { if (thread->GetRawState() != KThread::ThreadState_Runnable) {
bool current = false; bool current = false;
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) { for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
if (thread.GetPointerUnsafe() == Kernel::GetCurrentContext(i).current_thread) { if (thread == Kernel::GetCurrentContext(i).current_thread) {
current = true; current = true;
} }
break; break;
@ -508,7 +509,7 @@ namespace ams::kern {
} }
/* Get the thread context. */ /* Get the thread context. */
return this->GetThreadContextImpl(out, thread.GetPointerUnsafe(), context_flags); return this->GetThreadContextImpl(out, thread, context_flags);
} }
} }
@ -517,8 +518,9 @@ namespace ams::kern {
KScopedLightLock lk(this->lock); KScopedLightLock lk(this->lock);
/* Get the thread from its id. */ /* Get the thread from its id. */
KScopedAutoObject thread = KThread::GetThreadFromId(thread_id); KThread *thread = KThread::GetThreadFromId(thread_id);
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidId()); R_UNLESS(thread != nullptr, svc::ResultInvalidId());
ON_SCOPE_EXIT { thread->Close(); };
/* Verify that the thread is owned by our process. */ /* Verify that the thread is owned by our process. */
R_UNLESS(this->process == thread->GetOwnerProcess(), svc::ResultInvalidId()); R_UNLESS(this->process == thread->GetOwnerProcess(), svc::ResultInvalidId());
@ -528,7 +530,7 @@ namespace ams::kern {
/* Check that the thread is not the current one. */ /* Check that the thread is not the current one. */
/* NOTE: Nintendo does not check this, and thus the following loop will deadlock. */ /* NOTE: Nintendo does not check this, and thus the following loop will deadlock. */
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(), svc::ResultInvalidId()); R_UNLESS(thread != GetCurrentThreadPointer(), svc::ResultInvalidId());
/* Try to get the thread context until the thread isn't current on any core. */ /* Try to get the thread context until the thread isn't current on any core. */
while (true) { while (true) {
@ -541,7 +543,7 @@ namespace ams::kern {
if (thread->GetRawState() != KThread::ThreadState_Runnable) { if (thread->GetRawState() != KThread::ThreadState_Runnable) {
bool current = false; bool current = false;
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) { for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
if (thread.GetPointerUnsafe() == Kernel::GetCurrentContext(i).current_thread) { if (thread == Kernel::GetCurrentContext(i).current_thread) {
current = true; current = true;
} }
break; break;
@ -560,7 +562,7 @@ namespace ams::kern {
} }
/* Set the thread context. */ /* Set the thread context. */
return this->SetThreadContextImpl(ctx, thread.GetPointerUnsafe(), context_flags); return this->SetThreadContextImpl(ctx, thread, context_flags);
} }
} }

View file

@ -291,8 +291,9 @@ namespace ams::kern::svc {
R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle());
/* Get the thread from its id. */ /* Get the thread from its id. */
KScopedAutoObject thread = KThread::GetThreadFromId(thread_id); KThread *thread = KThread::GetThreadFromId(thread_id);
R_UNLESS(thread.IsNotNull(), svc::ResultInvalidThreadId()); R_UNLESS(thread != nullptr, svc::ResultInvalidThreadId());
ON_SCOPE_EXIT { thread->Close(); };
/* Get the process from the debug object. */ /* Get the process from the debug object. */
KScopedAutoObject process = debug->GetProcess(); KScopedAutoObject process = debug->GetProcess();