diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 3 |
3 files changed, 50 insertions, 3 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index d08b84bde..d3971a25e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -578,6 +578,10 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 578 | return ERR_INVALID_SIZE; | 578 | return ERR_INVALID_SIZE; |
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | if (!IsValidAddressRange(addr, size)) { | ||
| 582 | return ERR_INVALID_ADDRESS_STATE; | ||
| 583 | } | ||
| 584 | |||
| 581 | const auto permissions_type = static_cast<MemoryPermission>(permissions); | 585 | const auto permissions_type = static_cast<MemoryPermission>(permissions); |
| 582 | if (permissions_type != MemoryPermission::Read && | 586 | if (permissions_type != MemoryPermission::Read && |
| 583 | permissions_type != MemoryPermission::ReadWrite) { | 587 | permissions_type != MemoryPermission::ReadWrite) { |
| @@ -591,8 +595,14 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 591 | return ERR_INVALID_HANDLE; | 595 | return ERR_INVALID_HANDLE; |
| 592 | } | 596 | } |
| 593 | 597 | ||
| 594 | return shared_memory->Map(Core::CurrentProcess(), addr, permissions_type, | 598 | auto* const current_process = Core::CurrentProcess(); |
| 595 | MemoryPermission::DontCare); | 599 | const auto& vm_manager = current_process->VMManager(); |
| 600 | |||
| 601 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | ||
| 602 | return ERR_INVALID_MEMORY_RANGE; | ||
| 603 | } | ||
| 604 | |||
| 605 | return shared_memory->Map(current_process, addr, permissions_type, MemoryPermission::DontCare); | ||
| 596 | } | 606 | } |
| 597 | 607 | ||
| 598 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { | 608 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { |
| @@ -607,10 +617,24 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 607 | return ERR_INVALID_SIZE; | 617 | return ERR_INVALID_SIZE; |
| 608 | } | 618 | } |
| 609 | 619 | ||
| 620 | if (!IsValidAddressRange(addr, size)) { | ||
| 621 | return ERR_INVALID_ADDRESS_STATE; | ||
| 622 | } | ||
| 623 | |||
| 610 | auto& kernel = Core::System::GetInstance().Kernel(); | 624 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 611 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); | 625 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); |
| 626 | if (!shared_memory) { | ||
| 627 | return ERR_INVALID_HANDLE; | ||
| 628 | } | ||
| 629 | |||
| 630 | auto* const current_process = Core::CurrentProcess(); | ||
| 631 | const auto& vm_manager = current_process->VMManager(); | ||
| 632 | |||
| 633 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | ||
| 634 | return ERR_INVALID_MEMORY_RANGE; | ||
| 635 | } | ||
| 612 | 636 | ||
| 613 | return shared_memory->Unmap(Core::CurrentProcess(), addr); | 637 | return shared_memory->Unmap(current_process, addr); |
| 614 | } | 638 | } |
| 615 | 639 | ||
| 616 | /// Query process memory | 640 | /// Query process memory |
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 1e28ccbda..e1a34eef1 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -507,6 +507,26 @@ u64 VMManager::GetASLRRegionSize() const { | |||
| 507 | return aslr_region_end - aslr_region_base; | 507 | return aslr_region_end - aslr_region_base; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | bool VMManager::IsWithinASLRRegion(VAddr begin, u64 size) const { | ||
| 511 | const VAddr range_end = begin + size; | ||
| 512 | const VAddr aslr_start = GetASLRRegionBaseAddress(); | ||
| 513 | const VAddr aslr_end = GetASLRRegionEndAddress(); | ||
| 514 | |||
| 515 | if (aslr_start > begin || begin > range_end || range_end - 1 > aslr_end - 1) { | ||
| 516 | return false; | ||
| 517 | } | ||
| 518 | |||
| 519 | if (range_end > heap_region_base && heap_region_end > begin) { | ||
| 520 | return false; | ||
| 521 | } | ||
| 522 | |||
| 523 | if (range_end > map_region_base && map_region_end > begin) { | ||
| 524 | return false; | ||
| 525 | } | ||
| 526 | |||
| 527 | return true; | ||
| 528 | } | ||
| 529 | |||
| 510 | VAddr VMManager::GetCodeRegionBaseAddress() const { | 530 | VAddr VMManager::GetCodeRegionBaseAddress() const { |
| 511 | return code_region_base; | 531 | return code_region_base; |
| 512 | } | 532 | } |
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 4accde6b3..84c890224 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -211,6 +211,9 @@ public: | |||
| 211 | /// Gets the end address of the ASLR region. | 211 | /// Gets the end address of the ASLR region. |
| 212 | VAddr GetASLRRegionEndAddress() const; | 212 | VAddr GetASLRRegionEndAddress() const; |
| 213 | 213 | ||
| 214 | /// Determines whether or not the specified address range is within the ASLR region. | ||
| 215 | bool IsWithinASLRRegion(VAddr address, u64 size) const; | ||
| 216 | |||
| 214 | /// Gets the size of the ASLR region | 217 | /// Gets the size of the ASLR region |
| 215 | u64 GetASLRRegionSize() const; | 218 | u64 GetASLRRegionSize() const; |
| 216 | 219 | ||