diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index b06e780a0e..00be5940c3 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -258,6 +258,16 @@ void __InterruptsDoState(PointerWrap &p) intState.DoState(p); PendingInterrupt pi(0, 0); Do(p, pendingInterrupts, pi); + if (p.mode == p.MODE_READ) { + for (const PendingInterrupt &pend : pendingInterrupts) { + if (pend.intr < 0 || pend.intr >= PSP_NUMBER_INTERRUPTS) { + p.SetError(p.ERROR_FAILURE); + ERROR_LOG(Log::sceIntc, "Savestate failure: invalid pending interrupt %d", pend.intr); + pendingInterrupts.clear(); + return; + } + } + } Do(p, interruptsEnabled); Do(p, inInterrupt); Do(p, threadBeforeInterrupt); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index f9e37c7a69..98ed74a2ec 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -166,7 +166,7 @@ public: } PSPAction *createActionByType(int actionType) { - if (actionType < (int) types_.size() && types_[actionType] != NULL) { + if (actionType >= 0 && actionType < (int) types_.size() && types_[actionType] != NULL) { PSPAction *a = types_[actionType](); a->actionTypeID = actionType; return a; @@ -475,6 +475,14 @@ void PSPThread::DoState(PointerWrap &p) { } else { waitPausedForCallback = false; } + + // These index waitTypeFuncs and the ready queues. + if (p.mode == p.MODE_READ) { + if ((u32)nt.waitType >= NUM_WAITTYPES || (u32)nt.currentPriority >= ThreadQueueList::NUM_QUEUES || (u32)nt.initialPriority >= ThreadQueueList::NUM_QUEUES) { + ERROR_LOG(Log::sceKernel, "Savestate failure: invalid thread wait type or priority"); + p.SetError(p.ERROR_FAILURE); + } + } } @@ -585,6 +593,11 @@ void MipsCall::DoState(PointerWrap &p) Do(p, cbId); DoArray(p, args, ARRAY_SIZE(args)); Do(p, numArgs); + if (numArgs < 0 || numArgs > (int)ARRAY_SIZE(args)) { + ERROR_LOG(Log::sceKernel, "Savestate failure: invalid MipsCall arg count %d", numArgs); + p.SetError(p.ERROR_FAILURE); + return; + } // No longer used. u32 legacySavedIdRegister = 0; Do(p, legacySavedIdRegister);