mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
MemBlockInfo: Clamp marked ranges to the address space
A size that makes addr + size wrap around 32 bits had Split() build a slab that ends before it starts. Lookups then skipped it, and a later Merge() ran FillHeads() over it with a huge count, writing far outside heads_. Sizes come from games through HLE calls, and the large ones are recorded even without detailed mem info. Seen in a Play crash report, on the FlushMemInfo thread. FillHeads() also took the address one past the end of heads_ for a slab in the last slice, which Debug builds assert on. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8a50821839
commit
42f9af1744
2 files changed
+38
-5
No files matched your search
@@ -127,6 +127,14 @@ MemSlabMap::~MemSlabMap() {
|
||||
}
|
||||
|
||||
bool MemSlabMap::Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const char *tag, size_t tagLen) {
|
||||
if (addr >= MAX_SIZE) {
|
||||
return false;
|
||||
}
|
||||
// The size comes from the game. If addr + size wraps, Split() makes a slab that ends before it
|
||||
// starts, and a later FillHeads() on it writes far outside heads_.
|
||||
if (size > MAX_SIZE - addr) {
|
||||
size = MAX_SIZE - addr;
|
||||
}
|
||||
uint32_t end = addr + size;
|
||||
Slab *slab = FindSlab(addr);
|
||||
Slab *firstMatch = nullptr;
|
||||
@@ -430,11 +438,8 @@ void MemSlabMap::FillHeads(Slab *slab) {
|
||||
}
|
||||
|
||||
// Now replace all the rest - we definitely cover the start of them.
|
||||
Slab **next = &heads_[slice + 1];
|
||||
// We want to set slice + 1 through endSlice, inclusive.
|
||||
size_t c = endSlice - slice;
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
next[i] = slab;
|
||||
for (uint32_t i = slice + 1; i <= endSlice; ++i) {
|
||||
heads_[i] = slab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user