diff options
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 60 | ||||
| -rw-r--r-- | src/core/hle/service/ldr/ldr.cpp | 8 |
5 files changed, 64 insertions, 12 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 526b87241..9bda5c5b2 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -685,8 +685,8 @@ ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, | |||
| 685 | return ResultSuccess; | 685 | return ResultSuccess; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, | 688 | ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, |
| 689 | KMemoryPermission perm) { | 689 | KMemoryPermission perm) { |
| 690 | 690 | ||
| 691 | std::lock_guard lock{page_table_lock}; | 691 | std::lock_guard lock{page_table_lock}; |
| 692 | 692 | ||
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 770c4841c..b7ec38f06 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -41,7 +41,7 @@ public: | |||
| 41 | ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, | 41 | ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, |
| 42 | KMemoryPermission perm); | 42 | KMemoryPermission perm); |
| 43 | ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state); | 43 | ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state); |
| 44 | ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); | 44 | ResultCode SetProcessMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 45 | KMemoryInfo QueryInfo(VAddr addr); | 45 | KMemoryInfo QueryInfo(VAddr addr); |
| 46 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); | 46 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 47 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); | 47 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 76fd8c285..1aad061e1 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -528,7 +528,7 @@ void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { | |||
| 528 | std::lock_guard lock{HLE::g_hle_lock}; | 528 | std::lock_guard lock{HLE::g_hle_lock}; |
| 529 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 529 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 530 | KMemoryPermission permission) { | 530 | KMemoryPermission permission) { |
| 531 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); | 531 | page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); |
| 532 | }; | 532 | }; |
| 533 | 533 | ||
| 534 | kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), | 534 | kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f9d99bc51..f0cd8471e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1169,6 +1169,8 @@ static u32 GetCurrentProcessorNumber32(Core::System& system) { | |||
| 1169 | return GetCurrentProcessorNumber(system); | 1169 | return GetCurrentProcessorNumber(system); |
| 1170 | } | 1170 | } |
| 1171 | 1171 | ||
| 1172 | namespace { | ||
| 1173 | |||
| 1172 | constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { | 1174 | constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { |
| 1173 | switch (perm) { | 1175 | switch (perm) { |
| 1174 | case Svc::MemoryPermission::Read: | 1176 | case Svc::MemoryPermission::Read: |
| @@ -1179,10 +1181,24 @@ constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { | |||
| 1179 | } | 1181 | } |
| 1180 | } | 1182 | } |
| 1181 | 1183 | ||
| 1182 | constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) { | 1184 | [[maybe_unused]] constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) { |
| 1183 | return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare; | 1185 | return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare; |
| 1184 | } | 1186 | } |
| 1185 | 1187 | ||
| 1188 | constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) { | ||
| 1189 | switch (perm) { | ||
| 1190 | case Svc::MemoryPermission::None: | ||
| 1191 | case Svc::MemoryPermission::Read: | ||
| 1192 | case Svc::MemoryPermission::ReadWrite: | ||
| 1193 | case Svc::MemoryPermission::ReadExecute: | ||
| 1194 | return true; | ||
| 1195 | default: | ||
| 1196 | return false; | ||
| 1197 | } | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | } // Anonymous namespace | ||
| 1201 | |||
| 1186 | static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, | 1202 | static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, |
| 1187 | u64 size, Svc::MemoryPermission map_perm) { | 1203 | u64 size, Svc::MemoryPermission map_perm) { |
| 1188 | LOG_TRACE(Kernel_SVC, | 1204 | LOG_TRACE(Kernel_SVC, |
| @@ -1262,6 +1278,34 @@ static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle, | |||
| 1262 | return UnmapSharedMemory(system, shmem_handle, address, size); | 1278 | return UnmapSharedMemory(system, shmem_handle, address, size); |
| 1263 | } | 1279 | } |
| 1264 | 1280 | ||
| 1281 | static ResultCode SetProcessMemoryPermission(Core::System& system, Handle process_handle, | ||
| 1282 | VAddr address, u64 size, Svc::MemoryPermission perm) { | ||
| 1283 | LOG_TRACE(Kernel_SVC, | ||
| 1284 | "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | ||
| 1285 | process_handle, address, size, perm); | ||
| 1286 | |||
| 1287 | // Validate the address/size. | ||
| 1288 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | ||
| 1289 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 1290 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 1291 | R_UNLESS((address < address + size), ResultInvalidCurrentMemory); | ||
| 1292 | |||
| 1293 | // Validate the memory permission. | ||
| 1294 | R_UNLESS(IsValidProcessMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 1295 | |||
| 1296 | // Get the process from its handle. | ||
| 1297 | KScopedAutoObject process = | ||
| 1298 | system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); | ||
| 1299 | R_UNLESS(process.IsNotNull(), ResultInvalidHandle); | ||
| 1300 | |||
| 1301 | // Validate that the address is in range. | ||
| 1302 | auto& page_table = process->PageTable(); | ||
| 1303 | R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); | ||
| 1304 | |||
| 1305 | // Set the memory permission. | ||
| 1306 | return page_table.SetProcessMemoryPermission(address, size, ConvertToKMemoryPermission(perm)); | ||
| 1307 | } | ||
| 1308 | |||
| 1265 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1309 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1266 | VAddr page_info_address, Handle process_handle, | 1310 | VAddr page_info_address, Handle process_handle, |
| 1267 | VAddr address) { | 1311 | VAddr address) { |
| @@ -1459,10 +1503,14 @@ static void ExitProcess32(Core::System& system) { | |||
| 1459 | ExitProcess(system); | 1503 | ExitProcess(system); |
| 1460 | } | 1504 | } |
| 1461 | 1505 | ||
| 1462 | static constexpr bool IsValidVirtualCoreId(int32_t core_id) { | 1506 | namespace { |
| 1507 | |||
| 1508 | constexpr bool IsValidVirtualCoreId(int32_t core_id) { | ||
| 1463 | return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES)); | 1509 | return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES)); |
| 1464 | } | 1510 | } |
| 1465 | 1511 | ||
| 1512 | } // Anonymous namespace | ||
| 1513 | |||
| 1466 | /// Creates a new thread | 1514 | /// Creates a new thread |
| 1467 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, | 1515 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, |
| 1468 | VAddr stack_bottom, u32 priority, s32 core_id) { | 1516 | VAddr stack_bottom, u32 priority, s32 core_id) { |
| @@ -1846,7 +1894,9 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) { | |||
| 1846 | return ResetSignal(system, handle); | 1894 | return ResetSignal(system, handle); |
| 1847 | } | 1895 | } |
| 1848 | 1896 | ||
| 1849 | static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | 1897 | namespace { |
| 1898 | |||
| 1899 | constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | ||
| 1850 | switch (perm) { | 1900 | switch (perm) { |
| 1851 | case MemoryPermission::None: | 1901 | case MemoryPermission::None: |
| 1852 | case MemoryPermission::Read: | 1902 | case MemoryPermission::Read: |
| @@ -1857,6 +1907,8 @@ static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | |||
| 1857 | } | 1907 | } |
| 1858 | } | 1908 | } |
| 1859 | 1909 | ||
| 1910 | } // Anonymous namespace | ||
| 1911 | |||
| 1860 | /// Creates a TransferMemory object | 1912 | /// Creates a TransferMemory object |
| 1861 | static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, | 1913 | static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, |
| 1862 | MemoryPermission map_perm) { | 1914 | MemoryPermission map_perm) { |
| @@ -2588,7 +2640,7 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2588 | {0x70, nullptr, "CreatePort"}, | 2640 | {0x70, nullptr, "CreatePort"}, |
| 2589 | {0x71, nullptr, "ManageNamedPort"}, | 2641 | {0x71, nullptr, "ManageNamedPort"}, |
| 2590 | {0x72, nullptr, "ConnectToPort"}, | 2642 | {0x72, nullptr, "ConnectToPort"}, |
| 2591 | {0x73, nullptr, "SetProcessMemoryPermission"}, | 2643 | {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"}, |
| 2592 | {0x74, nullptr, "MapProcessMemory"}, | 2644 | {0x74, nullptr, "MapProcessMemory"}, |
| 2593 | {0x75, nullptr, "UnmapProcessMemory"}, | 2645 | {0x75, nullptr, "UnmapProcessMemory"}, |
| 2594 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, | 2646 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 32eff3b2a..3782703d2 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -396,12 +396,12 @@ public: | |||
| 396 | CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, | 396 | CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, |
| 397 | nro_header.segment_headers[DATA_INDEX].memory_size); | 397 | nro_header.segment_headers[DATA_INDEX].memory_size); |
| 398 | 398 | ||
| 399 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( | 399 | CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( |
| 400 | text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute)); | 400 | text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute)); |
| 401 | CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start, | 401 | CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( |
| 402 | Kernel::KMemoryPermission::Read)); | 402 | ro_start, data_start - ro_start, Kernel::KMemoryPermission::Read)); |
| 403 | 403 | ||
| 404 | return process->PageTable().SetCodeMemoryPermission( | 404 | return process->PageTable().SetProcessMemoryPermission( |
| 405 | data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); | 405 | data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); |
| 406 | } | 406 | } |
| 407 | 407 | ||