From: Yifan Lu Date: Wed, 23 Mar 2016 21:33:56 +0000 (-0500) Subject: Use after free on KSessionClient/Server and KClient/ServerPort when a handle is creat... X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=768d06aa0b165eaa8a9c25a6acfcff91ee2a02f1;p=console%2FXDS.git Use after free on KSessionClient/Server and KClient/ServerPort when a handle is created (and later closed) from a statically allocated object. --- diff --git a/include/kernel/Port.h b/include/kernel/Port.h index d78ce66..664b460 100644 --- a/include/kernel/Port.h +++ b/include/kernel/Port.h @@ -12,8 +12,8 @@ public: static const ClassName name = KPort_Class; - KClientPort m_Client; - KServerPort m_Server; + KClientPort *m_Client; + KServerPort *m_Server; char m_Name[9]; //this is not like on the 3DS but we use it like that for debugging private: }; diff --git a/include/kernel/Session.h b/include/kernel/Session.h index 12966a6..d888a3a 100644 --- a/include/kernel/Session.h +++ b/include/kernel/Session.h @@ -14,8 +14,8 @@ public: static const ClassName name = KSession_Class; - KServerSession m_Server; - KClientSession m_Client; + KServerSession *m_Server; + KClientSession *m_Client; KPort * m_owner; //this is for debugging KLinkedList m_openMemAddr; KLinkedList m_openMemSize; diff --git a/source/kernel/ClientPort.cpp b/source/kernel/ClientPort.cpp index 085b0b9..ce646e7 100644 --- a/source/kernel/ClientPort.cpp +++ b/source/kernel/ClientPort.cpp @@ -12,14 +12,14 @@ s32 KClientPort::connect(KClientSession* &sesion) if ( m_maxConnection > m_CurrentConnection) { //free the server so he can accept the connection - KThread* found = m_owner->m_Server.SynGetNextPrio(); + KThread* found = m_owner->m_Server->SynGetNextPrio(); if (found) { - m_owner->m_Server.SynFree(0, found); + m_owner->m_Server->SynFree(0, found); } KSession* sesi = new KSession(m_owner); - m_owner->m_Server.m_sessionToTake.AddItem(sesi); - sesion = &sesi->m_Client; + m_owner->m_Server->m_sessionToTake.AddItem(sesi); + sesion = sesi->m_Client; return Success; } else diff --git a/source/kernel/ClientSession.cpp b/source/kernel/ClientSession.cpp index 7899143..c9920d7 100644 --- a/source/kernel/ClientSession.cpp +++ b/source/kernel/ClientSession.cpp @@ -3,18 +3,18 @@ //tools void KClientSession::Destroy() { - m_owner->m_Server.SynFreeAll(0xC920181A); - m_owner->m_Server.m_killed = true; + m_owner->m_Server->SynFreeAll(0xC920181A); + m_owner->m_Server->m_killed = true; } bool KClientSession::Synchronization(KThread* thread, u32 &error) { - KThread * tnew = m_owner->m_Server.SynGetNextPrio(); - if (tnew && !m_owner->m_Server.m_processingCmd) + KThread * tnew = m_owner->m_Server->SynGetNextPrio(); + if (tnew && !m_owner->m_Server->m_processingCmd) { - m_owner->m_Server.m_waitingForCmdResp = thread; - m_owner->m_Server.m_processingCmd = tnew; + m_owner->m_Server->m_waitingForCmdResp = thread; + m_owner->m_Server->m_processingCmd = tnew; m_owner->Communicate(thread,tnew , false); - m_owner->m_Server.SynFree(0, tnew); + m_owner->m_Server->SynFree(0, tnew); } return true; //stall } diff --git a/source/kernel/Port.cpp b/source/kernel/Port.cpp index 75ab424..1472a2a 100644 --- a/source/kernel/Port.cpp +++ b/source/kernel/Port.cpp @@ -3,13 +3,16 @@ //tools -KPort::KPort(char* name, u32 maxconnection) : m_Client(name, maxconnection, this), m_Server(name, maxconnection, this) +KPort::KPort(char* name, u32 maxconnection) : m_Client(new KClientPort(name, maxconnection, this)), m_Server(new KServerPort(name, maxconnection, this)) { strncpy(m_Name, name, 8); + m_Client->AcquireReference(); + m_Server->AcquireReference(); } KPort::~KPort() { - + m_Client->ReleaseReference(); + m_Server->ReleaseReference(); } bool KPort::IsInstanceOf(ClassName name) { diff --git a/source/kernel/ServerPort.cpp b/source/kernel/ServerPort.cpp index e782ea9..4be2323 100644 --- a/source/kernel/ServerPort.cpp +++ b/source/kernel/ServerPort.cpp @@ -24,7 +24,7 @@ KServerSession * KServerPort::AcceptSesion() m_sessionToTake.RemoveItem(m_sessionToTake.list); if (s == NULL) return NULL; - return &s->m_Server; + return s->m_Server; } bool KServerPort::IsInstanceOf(ClassName name) { diff --git a/source/kernel/ServerSession.cpp b/source/kernel/ServerSession.cpp index d1cfdf9..1075886 100644 --- a/source/kernel/ServerSession.cpp +++ b/source/kernel/ServerSession.cpp @@ -8,11 +8,11 @@ void KServerSession::Destroy() { } bool KServerSession::Synchronization(KThread* thread, u32 &error) { - KThread * tnew = m_owner->m_Client.SynGetNextPrio(); - if (tnew && !m_owner->m_Server.m_waitingForCmdResp) + KThread * tnew = m_owner->m_Client->SynGetNextPrio(); + if (tnew && !m_owner->m_Server->m_waitingForCmdResp) { - m_owner->m_Server.m_waitingForCmdResp = tnew; - m_owner->m_Server.m_processingCmd = thread; + m_owner->m_Server->m_waitingForCmdResp = tnew; + m_owner->m_Server->m_processingCmd = thread; m_owner->Communicate(tnew, thread, false); return false; } @@ -45,7 +45,7 @@ s32 KServerSession::reply(KThread * sender) m_owner->Communicate(sender, m_waitingForCmdResp,true); - m_owner->m_Client.SynFree(0, m_waitingForCmdResp); + m_owner->m_Client->SynFree(0, m_waitingForCmdResp); m_processingCmd = NULL; m_waitingForCmdResp = NULL; diff --git a/source/kernel/Session.cpp b/source/kernel/Session.cpp index f35eea5..80c7de8 100644 --- a/source/kernel/Session.cpp +++ b/source/kernel/Session.cpp @@ -5,13 +5,16 @@ //tools -KSession::KSession(KPort * owner) : m_Server(this), m_Client(this) +KSession::KSession(KPort * owner) : m_Server(new KServerSession(this)), m_Client(new KClientSession(this)) { m_owner = owner; + m_Client->AcquireReference(); + m_Server->AcquireReference(); } KSession::~KSession() { - + m_Client->ReleaseReference(); + m_Server->ReleaseReference(); } bool KSession::IsInstanceOf(ClassName name) { if (name == KSession::name) diff --git a/source/kernel/Swi.cpp b/source/kernel/Swi.cpp index 654d89e..096bc21 100644 --- a/source/kernel/Swi.cpp +++ b/source/kernel/Swi.cpp @@ -832,7 +832,7 @@ void ProcessSwi(u8 swi, u32 Reg[15], KThread * currentThread) //found it KClientSession* ses; u32 hand; - if (temp->data->m_Client.connect(ses) == Success) + if (temp->data->m_Client->connect(ses) == Success) { s32 ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand, ses); if (ret != Success) @@ -1192,7 +1192,7 @@ void ProcessSwi(u8 swi, u32 Reg[15], KThread * currentThread) currentThread->m_owner->m_Kernel->m_Portlist.AddItem(port); u32 hand1 = 0; - s32 ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand1, &port->m_Server); + s32 ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand1, port->m_Server); if (ret != Success) { Reg[0] = SVCERROR_CREATE_HANLE; @@ -1211,7 +1211,7 @@ void ProcessSwi(u8 swi, u32 Reg[15], KThread * currentThread) return; } u32 hand2 = 0; - ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand2, &port->m_Client); + ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand2, port->m_Client); if (ret != Success) { Reg[0] = SVCERROR_CREATE_HANLE; @@ -1291,7 +1291,7 @@ void ProcessSwi(u8 swi, u32 Reg[15], KThread * currentThread) KSession* sesi = new KSession(); u32 hand1,hand2; - s32 ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand1, &sesi->m_Server); + s32 ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand1, sesi->m_Server); if (ret != Success) { Reg[0] = SVCERROR_CREATE_HANLE; @@ -1300,7 +1300,7 @@ void ProcessSwi(u8 swi, u32 Reg[15], KThread * currentThread) #endif return; } - ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand2, &sesi->m_Client); + ret = currentThread->m_owner->GetHandleTable()->CreateHandle(hand2, sesi->m_Client); if (ret != Success) { Reg[0] = SVCERROR_CREATE_HANLE;