mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
Validate requested dmem range in MapMemory
Handles a rare edge case that only comes up when modding Driveclub
This commit is contained in:
parent
e389d03601
commit
607bd59a9c
@ -320,6 +320,28 @@ s32 MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, u64 size, Memo
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
// Validate the requested physical address range
|
||||
if (phys_addr != -1) {
|
||||
auto validated_size = 0;
|
||||
do {
|
||||
auto dmem_area = FindDmemArea(phys_addr + validated_size)->second;
|
||||
// If any requested dmem area is not allocated, return an error.
|
||||
if (dmem_area.is_free) {
|
||||
LOG_ERROR(Kernel_Vmm, "Unable to map {:#x} bytes at physical address {:#x}", size,
|
||||
phys_addr);
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
// Track how much we've validated.
|
||||
validated_size += dmem_area.size - (phys_addr + validated_size - dmem_area.base);
|
||||
} while (validated_size < size && phys_addr + validated_size < GetTotalDirectSize());
|
||||
// If the requested range goes outside the dmem map, return an error.
|
||||
if (validated_size < size) {
|
||||
LOG_ERROR(Kernel_Vmm, "Unable to map {:#x} bytes at physical address {:#x}", size,
|
||||
phys_addr);
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the minumum address to SystemManagedVirtualBase to prevent hardware-specific issues.
|
||||
VAddr mapped_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr;
|
||||
|
||||
|
@ -63,8 +63,8 @@ enum class VMAType : u32 {
|
||||
|
||||
struct DirectMemoryArea {
|
||||
PAddr base = 0;
|
||||
size_t size = 0;
|
||||
int memory_type = 0;
|
||||
u64 size = 0;
|
||||
s32 memory_type = 0;
|
||||
bool is_pooled = false;
|
||||
bool is_free = true;
|
||||
|
||||
@ -72,6 +72,10 @@ struct DirectMemoryArea {
|
||||
return base + size;
|
||||
}
|
||||
|
||||
bool Contains(PAddr addr, u64 size) const {
|
||||
return addr >= base && (addr + size) <= (base + this->size);
|
||||
}
|
||||
|
||||
bool CanMergeWith(const DirectMemoryArea& next) const {
|
||||
if (base + size != next.base) {
|
||||
return false;
|
||||
@ -88,7 +92,7 @@ struct DirectMemoryArea {
|
||||
|
||||
struct VirtualMemoryArea {
|
||||
VAddr base = 0;
|
||||
size_t size = 0;
|
||||
u64 size = 0;
|
||||
PAddr phys_base = 0;
|
||||
VMAType type = VMAType::Free;
|
||||
MemoryProt prot = MemoryProt::NoAccess;
|
||||
|
Loading…
Reference in New Issue
Block a user