mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-20 17:59:08 +02:00
SaveState: Reject implausible event counts, ids and CPU speed from a state
They came straight from the file: a CPU frequency of 0 divided by zero, and counts or ids sized tables of up to tens of gigabytes, or tripped an assert. A file like that now fails to load like any other broken state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
79d340f4fe
commit
eec6afaeca
2 files changed
+19
-1
No files matched your search
@@ -44,6 +44,8 @@ int CPU_HZ = 222000000;
|
||||
namespace CoreTiming {
|
||||
|
||||
static std::vector<EventType> event_types;
|
||||
// Far more than ever registered. Counts and ids from a savestate are checked against it.
|
||||
static constexpr int MAX_EVENT_TYPES = 4096;
|
||||
// Only used during restore.
|
||||
static std::set<int> usedEventTypes;
|
||||
static std::set<int> restoredEventTypes;
|
||||
@@ -189,6 +191,9 @@ void RestoreRegisterEvent(int &event_type, const char *name, TimedCallback callb
|
||||
// Some old states have a duplicate restore, do our best to fix...
|
||||
if (restoredEventTypes.count(event_type) != 0)
|
||||
event_type = -1;
|
||||
// Straight from the file, so don't let a bogus id size the table.
|
||||
if (event_type < -1 || event_type >= MAX_EVENT_TYPES)
|
||||
event_type = -1;
|
||||
if (event_type == -1)
|
||||
event_type = nextEventTypeRestoreId++;
|
||||
if (event_type >= (int)event_types.size()) {
|
||||
@@ -542,6 +547,11 @@ void DoState(PointerWrap &p) {
|
||||
int n = (int)event_types.size();
|
||||
int current = n;
|
||||
Do(p, n);
|
||||
if (n < 0 || n > MAX_EVENT_TYPES) {
|
||||
ERROR_LOG(Log::SaveState, "Savestate failure: implausible event type count %d", n);
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
if (n > current) {
|
||||
if (p.mode != PointerWrap::MODE_READ) {
|
||||
WARN_LOG(Log::SaveState, "Savestate failure: more events than current");
|
||||
@@ -579,6 +589,13 @@ void DoState(PointerWrap &p) {
|
||||
}
|
||||
|
||||
Do(p, CPU_HZ);
|
||||
if (CPU_HZ <= 0) {
|
||||
// Everything divides by it.
|
||||
ERROR_LOG(Log::SaveState, "Savestate failure: bad CPU frequency %d", (int)CPU_HZ);
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
CPU_HZ = 222000000;
|
||||
return;
|
||||
}
|
||||
Do(p, slicelength);
|
||||
Do(p, globalTimer);
|
||||
Do(p, idledCycles);
|
||||
|
||||
+2
-1
@@ -497,7 +497,8 @@ void HLEDoState(PointerWrap &p) {
|
||||
delete action;
|
||||
}
|
||||
mipsCallActions.clear();
|
||||
if (actions < 0) {
|
||||
// Each action takes at least its type id.
|
||||
if (actions < 0 || (size_t)actions > p.Remaining() / sizeof(int)) {
|
||||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user