kernel: Skip address range checks for privileged memory (un)map. (#6407)

This commit is contained in:
Steveice10 2023-04-06 05:30:13 -07:00 committed by GitHub
parent 495e5dadd7
commit 287ce1e56f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -377,20 +377,14 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
bool privileged) { bool privileged) {
LOG_DEBUG(Kernel, "Map memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}", target, LOG_DEBUG(Kernel, "Map memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}", target,
source, size, perms); source, size, perms);
if (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END || if (!privileged && (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END ||
source + size < source) { source + size < source)) {
LOG_ERROR(Kernel, "Invalid source address"); LOG_ERROR(Kernel, "Invalid source address");
return ERR_INVALID_ADDRESS; return ERR_INVALID_ADDRESS;
} }
// TODO(wwylele): check target address range. Is it also restricted to heap region? // TODO(wwylele): check target address range. Is it also restricted to heap region?
auto vma = vm_manager.FindVMA(target);
if (vma->second.type != VMAType::Free || vma->second.base + vma->second.size < target + size) {
LOG_ERROR(Kernel, "Trying to map to already allocated memory");
return ERR_INVALID_ADDRESS_STATE;
}
// Check range overlapping // Check range overlapping
if (source - target < size || target - source < size) { if (source - target < size || target - source < size) {
if (privileged) { if (privileged) {
@ -408,6 +402,12 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
} }
} }
auto vma = vm_manager.FindVMA(target);
if (vma->second.type != VMAType::Free || vma->second.base + vma->second.size < target + size) {
LOG_ERROR(Kernel, "Trying to map to already allocated memory");
return ERR_INVALID_ADDRESS_STATE;
}
MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased; MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased;
MemoryState target_state = privileged ? MemoryState::AliasCode : MemoryState::Alias; MemoryState target_state = privileged ? MemoryState::AliasCode : MemoryState::Alias;
VMAPermission source_perm = privileged ? VMAPermission::None : VMAPermission::ReadWrite; VMAPermission source_perm = privileged ? VMAPermission::None : VMAPermission::ReadWrite;
@ -432,17 +432,14 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
bool privileged) { bool privileged) {
LOG_DEBUG(Kernel, "Unmap memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}", LOG_DEBUG(Kernel, "Unmap memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}",
target, source, size, perms); target, source, size, perms);
if (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END || if (!privileged && (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END ||
source + size < source) { source + size < source)) {
LOG_ERROR(Kernel, "Invalid source address"); LOG_ERROR(Kernel, "Invalid source address");
return ERR_INVALID_ADDRESS; return ERR_INVALID_ADDRESS;
} }
// TODO(wwylele): check target address range. Is it also restricted to heap region? // TODO(wwylele): check target address range. Is it also restricted to heap region?
// TODO(wwylele): check that the source and the target are actually a pair created by Map
// Should return error 0xD8E007F5 in this case
if (source - target < size || target - source < size) { if (source - target < size || target - source < size) {
if (privileged) { if (privileged) {
if (source == target) { if (source == target) {
@ -459,6 +456,9 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
} }
} }
// TODO(wwylele): check that the source and the target are actually a pair created by Map
// Should return error 0xD8E007F5 in this case
MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased; MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased;
CASCADE_CODE(vm_manager.UnmapRange(target, size)); CASCADE_CODE(vm_manager.UnmapRange(target, size));