mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
vm: Fix an overflow at vm::alloc, fix vm::find_map (#10760)
* The statement addr += align could have overflowed resulting in either infinite loop or allocating memory outside of the region (illegal). Add a check checking if it's the last iteration of the loop, then break without adding. * vm::find_map condition didn't consider the size of the map to be allocated, allowing illegal occupation of [<=0xB000'0000]-0xCFFF'FFFF. (0xC000'0000-0xCFFF'FFFF is reserved for RSX)
This commit is contained in:
parent
b0e352c44e
commit
2d9929059f
@ -1205,15 +1205,29 @@ namespace vm
|
||||
shm = std::make_shared<utils::shm>(size);
|
||||
}
|
||||
|
||||
const u32 max = (this->addr + this->size - size) & (0 - align);
|
||||
|
||||
u32 addr = utils::align(this->addr, align);
|
||||
|
||||
if (this->addr > std::min(max, addr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
// Search for an appropriate place (unoptimized)
|
||||
for (u32 addr = utils::align(this->addr, align); u64{addr} + size <= u64{this->addr} + this->size; addr += align)
|
||||
for (;; addr += align)
|
||||
{
|
||||
if (try_alloc(addr, pflags, size, std::move(shm)))
|
||||
{
|
||||
return addr + (flags & stack_guarded ? 0x1000 : 0);
|
||||
}
|
||||
|
||||
if (addr == max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1417,12 +1431,24 @@ namespace vm
|
||||
|
||||
static std::shared_ptr<block_t> _find_map(u32 size, u32 align, u64 flags)
|
||||
{
|
||||
for (u32 addr = utils::align<u32>(0x20000000, align); addr - 1 < 0xC0000000 - 1; addr += align)
|
||||
const u32 max = (0xC0000000 - size) & (0 - align);
|
||||
|
||||
if (size > 0xC0000000 - 0x20000000 || max < 0x20000000)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (u32 addr = utils::align<u32>(0x20000000, align);; addr += align)
|
||||
{
|
||||
if (_test_map(addr, size))
|
||||
{
|
||||
return std::make_shared<block_t>(addr, size, flags);
|
||||
}
|
||||
|
||||
if (addr == max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user