Kernel: Validate thread, MipsCall and interrupt indices from savestates

waitType, thread priorities, MipsCall::numArgs, action type IDs and pending
interrupt numbers all index host arrays (some of them function pointer
tables) without further checks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-09 15:32:05 +02:00
1 parent b0e8b20acd
commit 8e6f8de19b
2 files changed
+24 -1

No files matched your search

+14 -1
View File
@@ -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);