From 281437c811847adbc38b69ef3638996c666f65c3 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sat, 20 Nov 2021 20:05:02 -0500
Subject: [PATCH 1/3] kernel: KPageTable: Rename SetCodeMemoryPermission to
 SetProcessMemoryPermission

---
 src/core/hle/kernel/k_page_table.cpp | 4 ++--
 src/core/hle/kernel/k_page_table.h   | 2 +-
 src/core/hle/kernel/k_process.cpp    | 2 +-
 src/core/hle/service/ldr/ldr.cpp     | 8 ++++----
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 526b872413..9bda5c5b20 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,
     return ResultSuccess;
 }
 
-ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size,
-                                               KMemoryPermission perm) {
+ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size,
+                                                  KMemoryPermission perm) {
 
     std::lock_guard lock{page_table_lock};
 
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 770c4841c4..b7ec38f060 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -41,7 +41,7 @@ public:
     ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state,
                         KMemoryPermission perm);
     ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state);
-    ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm);
+    ResultCode SetProcessMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm);
     KMemoryInfo QueryInfo(VAddr addr);
     ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm);
     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 76fd8c285c..1aad061e16 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) {
     std::lock_guard lock{HLE::g_hle_lock};
     const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
                                       KMemoryPermission permission) {
-        page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission);
+        page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
     };
 
     kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(),
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 32eff3b2a1..3782703d20 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -396,12 +396,12 @@ public:
         CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start,
                  nro_header.segment_headers[DATA_INDEX].memory_size);
 
-        CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(
+        CASCADE_CODE(process->PageTable().SetProcessMemoryPermission(
             text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute));
-        CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start,
-                                                                  Kernel::KMemoryPermission::Read));
+        CASCADE_CODE(process->PageTable().SetProcessMemoryPermission(
+            ro_start, data_start - ro_start, Kernel::KMemoryPermission::Read));
 
-        return process->PageTable().SetCodeMemoryPermission(
+        return process->PageTable().SetProcessMemoryPermission(
             data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite);
     }
 

From 2726d705f8dde6d8fcbcfcd55e065a0598e10969 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sat, 20 Nov 2021 20:23:59 -0500
Subject: [PATCH 2/3] kernel: svc: Implement SetProcessMemoryPermission

- Used by Skyline modding framework
---
 src/core/hle/kernel/svc.cpp | 42 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f9d99bc514..23dc44780e 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1183,6 +1183,18 @@ constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) {
     return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare;
 }
 
+constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) {
+    switch (perm) {
+    case Svc::MemoryPermission::None:
+    case Svc::MemoryPermission::Read:
+    case Svc::MemoryPermission::ReadWrite:
+    case Svc::MemoryPermission::ReadExecute:
+        return true;
+    default:
+        return false;
+    }
+}
+
 static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
                                   u64 size, Svc::MemoryPermission map_perm) {
     LOG_TRACE(Kernel_SVC,
@@ -1262,6 +1274,34 @@ static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle,
     return UnmapSharedMemory(system, shmem_handle, address, size);
 }
 
+static ResultCode SetProcessMemoryPermission(Core::System& system, Handle process_handle,
+                                             VAddr address, u64 size, Svc::MemoryPermission perm) {
+    LOG_TRACE(Kernel_SVC,
+              "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
+              process_handle, address, size, perm);
+
+    // Validate the address/size.
+    R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
+    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
+    R_UNLESS(size > 0, ResultInvalidSize);
+    R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
+
+    // Validate the memory permission.
+    R_UNLESS(IsValidProcessMemoryPermission(perm), ResultInvalidNewMemoryPermission);
+
+    // Get the process from its handle.
+    KScopedAutoObject process =
+        system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle);
+    R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
+
+    // Validate that the address is in range.
+    auto& page_table = process->PageTable();
+    R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
+
+    // Set the memory permission.
+    return page_table.SetProcessMemoryPermission(address, size, ConvertToKMemoryPermission(perm));
+}
+
 static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
                                      VAddr page_info_address, Handle process_handle,
                                      VAddr address) {
@@ -2588,7 +2628,7 @@ static const FunctionDef SVC_Table_64[] = {
     {0x70, nullptr, "CreatePort"},
     {0x71, nullptr, "ManageNamedPort"},
     {0x72, nullptr, "ConnectToPort"},
-    {0x73, nullptr, "SetProcessMemoryPermission"},
+    {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"},
     {0x74, nullptr, "MapProcessMemory"},
     {0x75, nullptr, "UnmapProcessMemory"},
     {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"},

From 5cf93c134684f7548572ff27131901f5909725fa Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sat, 20 Nov 2021 21:54:46 -0500
Subject: [PATCH 3/3] kernel: svc: Move all IsValid functions to an anonymous
 namespace

---
 src/core/hle/kernel/svc.cpp | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 23dc44780e..f0cd8471e8 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) {
     return GetCurrentProcessorNumber(system);
 }
 
+namespace {
+
 constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) {
     switch (perm) {
     case Svc::MemoryPermission::Read:
@@ -1179,7 +1181,7 @@ constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) {
     }
 }
 
-constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) {
+[[maybe_unused]] constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) {
     return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare;
 }
 
@@ -1195,6 +1197,8 @@ constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) {
     }
 }
 
+} // Anonymous namespace
+
 static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
                                   u64 size, Svc::MemoryPermission map_perm) {
     LOG_TRACE(Kernel_SVC,
@@ -1499,10 +1503,14 @@ static void ExitProcess32(Core::System& system) {
     ExitProcess(system);
 }
 
-static constexpr bool IsValidVirtualCoreId(int32_t core_id) {
+namespace {
+
+constexpr bool IsValidVirtualCoreId(int32_t core_id) {
     return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES));
 }
 
+} // Anonymous namespace
+
 /// Creates a new thread
 static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
                                VAddr stack_bottom, u32 priority, s32 core_id) {
@@ -1886,7 +1894,9 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) {
     return ResetSignal(system, handle);
 }
 
-static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
+namespace {
+
+constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
     switch (perm) {
     case MemoryPermission::None:
     case MemoryPermission::Read:
@@ -1897,6 +1907,8 @@ static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
     }
 }
 
+} // Anonymous namespace
+
 /// Creates a TransferMemory object
 static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
                                        MemoryPermission map_perm) {