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 d3c9d50b5..3b8a2e230 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -584,6 +584,10 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 584 | return ERR_INVALID_SIZE; | 584 | return ERR_INVALID_SIZE; |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | if (!IsValidAddressRange(addr, size)) { | ||
| 588 | return ERR_INVALID_ADDRESS_STATE; | ||
| 589 | } | ||
| 590 | |||
| 587 | const auto permissions_type = static_cast<MemoryPermission>(permissions); | 591 | const auto permissions_type = static_cast<MemoryPermission>(permissions); |
| 588 | if (permissions_type != MemoryPermission::Read && | 592 | if (permissions_type != MemoryPermission::Read && |
| 589 | permissions_type != MemoryPermission::ReadWrite) { | 593 | permissions_type != MemoryPermission::ReadWrite) { |
| @@ -597,8 +601,14 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 597 | return ERR_INVALID_HANDLE; | 601 | return ERR_INVALID_HANDLE; |
| 598 | } | 602 | } |
| 599 | 603 | ||
| 600 | return shared_memory->Map(Core::CurrentProcess(), addr, permissions_type, | 604 | auto* const current_process = Core::CurrentProcess(); |
| 601 | MemoryPermission::DontCare); | 605 | const auto& vm_manager = current_process->VMManager(); |
| 606 | |||
| 607 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | ||
| 608 | return ERR_INVALID_MEMORY_RANGE; | ||
| 609 | } | ||
| 610 | |||
| 611 | return shared_memory->Map(current_process, addr, permissions_type, MemoryPermission::DontCare); | ||
| 602 | } | 612 | } |
| 603 | 613 | ||
| 604 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { | 614 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { |
| @@ -613,10 +623,24 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 613 | return ERR_INVALID_SIZE; | 623 | return ERR_INVALID_SIZE; |
| 614 | } | 624 | } |
| 615 | 625 | ||
| 626 | if (!IsValidAddressRange(addr, size)) { | ||
| 627 | return ERR_INVALID_ADDRESS_STATE; | ||
| 628 | } | ||
| 629 | |||
| 616 | auto& kernel = Core::System::GetInstance().Kernel(); | 630 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 617 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); | 631 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); |
| 632 | if (!shared_memory) { | ||
| 633 | return ERR_INVALID_HANDLE; | ||
| 634 | } | ||
| 635 | |||
| 636 | auto* const current_process = Core::CurrentProcess(); | ||
| 637 | const auto& vm_manager = current_process->VMManager(); | ||
| 638 | |||
| 639 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | ||
| 640 | return ERR_INVALID_MEMORY_RANGE; | ||
| 641 | } | ||
| 618 | 642 | ||
| 619 | return shared_memory->Unmap(Core::CurrentProcess(), addr); | 643 | return shared_memory->Unmap(current_process, addr); |
| 620 | } | 644 | } |
| 621 | 645 | ||
| 622 | /// Query process memory | 646 | /// 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 | ||