From 14065ae7cb139a7b2639ace7701038c36d9abd6b Mon Sep 17 00:00:00 2001 From: Zephyron Date: Mon, 3 Feb 2025 16:13:21 +1000 Subject: [PATCH] kernel/svc: Refactor UnmapProcessCodeMemory validation Improve the validation logic in UnmapProcessCodeMemory by: - Add missing size validation check at the start - Reorganize validation checks into logical groups - Simplify error handling using R_UNLESS macros - Remove redundant page table range check - Add copyright notice for Citron Emulator Project - Add ResultInvalidSize constant definition The changes make the validation code more concise and easier to follow while maintaining the same validation requirements. Error handling is now more consistent with other SVC implementations. --- src/core/hle/kernel/svc.h | 3 + .../hle/kernel/svc/svc_process_memory.cpp | 62 +++++-------------- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index 828f39611..28d36318c 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later // This file is automatically generated using svc_generator.py. @@ -17,6 +18,8 @@ class System; namespace Kernel::Svc { +constexpr Result ResultInvalidSize{ErrorModule::Kernel, 104}; + // clang-format off Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size); Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm); diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp index e1427947b..4c74a45f0 100644 --- a/src/core/hle/kernel/svc/svc_process_memory.cpp +++ b/src/core/hle/kernel/svc/svc_process_memory.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" @@ -191,62 +192,33 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst } Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, - u64 src_address, u64 size) { + u64 src_address, u64 size) { LOG_DEBUG(Kernel_SVC, "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " "size=0x{:016X}", process_handle, dst_address, src_address, size); - if (!Common::Is4KBAligned(dst_address)) { - LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", - dst_address); - R_THROW(ResultInvalidAddress); - } + // Add size validation + R_UNLESS(size != 0, ResultInvalidSize); + R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); - if (!Common::Is4KBAligned(src_address)) { - LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", - src_address); - R_THROW(ResultInvalidAddress); - } + // Validate address alignment + R_UNLESS(Common::IsAligned(dst_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(src_address, PageSize), ResultInvalidAddress); - if (size == 0 || !Common::Is4KBAligned(size)) { - LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X}).", size); - R_THROW(ResultInvalidSize); - } + // Validate address ranges + R_UNLESS(IsValidAddressRange(dst_address, size), ResultInvalidCurrentMemory); + R_UNLESS(IsValidAddressRange(src_address, size), ResultInvalidCurrentMemory); - if (!IsValidAddressRange(dst_address, size)) { - LOG_ERROR(Kernel_SVC, - "Destination address range overflows the address space (dst_address=0x{:016X}, " - "size=0x{:016X}).", - dst_address, size); - R_THROW(ResultInvalidCurrentMemory); - } - - if (!IsValidAddressRange(src_address, size)) { - LOG_ERROR(Kernel_SVC, - "Source address range overflows the address space (src_address=0x{:016X}, " - "size=0x{:016X}).", - src_address, size); - R_THROW(ResultInvalidCurrentMemory); - } - - const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); - if (process.IsNull()) { - LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", - process_handle); - R_THROW(ResultInvalidHandle); - } + // Get the process from its handle + KScopedAutoObject process = + GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject(process_handle); + R_UNLESS(process.IsNotNull(), ResultInvalidHandle); + // Get the page table auto& page_table = process->GetPageTable(); - if (!page_table.Contains(src_address, size)) { - LOG_ERROR(Kernel_SVC, - "Source address range is not within the address space (src_address=0x{:016X}, " - "size=0x{:016X}).", - src_address, size); - R_THROW(ResultInvalidCurrentMemory); - } + // Perform the unmapping R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size)); }