summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Lioncash2018-10-17 22:39:21 -0400
committerGravatar Lioncash2018-10-18 02:01:21 -0400
commit33830aa65ac58a03a91de9ac4fc8d91fe28f6d4e (patch)
tree54ec4efc8021d87b2d5110c9aa047d5a8f5d3fe0 /src/core/hle/kernel
parentMerge pull request #1444 from ogniK5377/better-hid (diff)
downloadyuzu-33830aa65ac58a03a91de9ac4fc8d91fe28f6d4e.tar.gz
yuzu-33830aa65ac58a03a91de9ac4fc8d91fe28f6d4e.tar.xz
yuzu-33830aa65ac58a03a91de9ac4fc8d91fe28f6d4e.zip
svc: Add missing sanitizing checks for MapSharedMemory/UnmapSharedMemory
Now that the changes clarifying the address spaces has been merged, we can wrap the checks that the kernel performs when mapping shared memory (and other forms of memory) into its own helper function and then use those within MapSharedMemory and UnmapSharedMemory to complete the sanitizing checks that are supposed to be done.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/svc.cpp30
-rw-r--r--src/core/hle/kernel/vm_manager.cpp20
-rw-r--r--src/core/hle/kernel/vm_manager.h3
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
598static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { 608static 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
510bool 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
510VAddr VMManager::GetCodeRegionBaseAddress() const { 530VAddr 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