From 9677522e6c27e81ba06aeb5a8c4e09514644018f Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 7 Jul 2026 20:02:26 +0200 Subject: [PATCH] [core/hle/kernel/svc] add missing CanContain check for {Un}MapProcessCodeMemory, remove 4KB align func (#4164) does what it says, adds a missing check for that specific SVC also removes that 4kb "helper" function which is just a fancy "IsAligned" Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4164 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey --- src/audio_core/renderer/memory/pool_mapper.cpp | 8 ++++++-- src/common/alignment.h | 13 +++++-------- src/core/hle/kernel/svc/svc_memory.cpp | 11 +++++------ src/core/hle/kernel/svc/svc_physical_memory.cpp | 10 +++++----- src/core/hle/kernel/svc/svc_process_memory.cpp | 14 ++++++++------ 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp index e47eb66d51..fcd923d35a 100644 --- a/src/audio_core/renderer/memory/pool_mapper.cpp +++ b/src/audio_core/renderer/memory/pool_mapper.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -181,8 +184,9 @@ MemoryPoolInfo::ResultState PoolMapper::Update(MemoryPoolInfo& pool, return MemoryPoolInfo::ResultState::Success; } - if (in_params.address == 0 || in_params.size == 0 || !Common::Is4KBAligned(in_params.address) || - !Common::Is4KBAligned(in_params.size)) { + if (in_params.address == 0 || in_params.size == 0 + || !Common::IsAligned(in_params.address, Core::Memory::YUZU_PAGESIZE) + || !Common::IsAligned(in_params.size, Core::Memory::YUZU_PAGESIZE)) { return MemoryPoolInfo::ResultState::BadParam; } diff --git a/src/common/alignment.h b/src/common/alignment.h index fc5c26898a..3612ab0a86 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Jannik Vogel // SPDX-License-Identifier: CC0-1.0 @@ -34,12 +37,6 @@ template return static_cast(value - value % size); } -template - requires std::is_unsigned_v -[[nodiscard]] constexpr bool Is4KBAligned(T value) { - return (value & 0xFFF) == 0; -} - template requires std::is_unsigned_v [[nodiscard]] constexpr bool IsWordAligned(T value) { @@ -48,9 +45,9 @@ template template requires std::is_integral_v -[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) { +[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) noexcept { using U = typename std::make_unsigned_t; - const U mask = static_cast(alignment - 1); + const U mask = U(alignment - 1); return (value & mask) == 0; } diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp index 740e11ff87..ffe7eb42f6 100644 --- a/src/core/hle/kernel/svc/svc_memory.cpp +++ b/src/core/hle/kernel/svc/svc_memory.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -32,14 +32,13 @@ constexpr bool IsValidAddressRange(u64 address, u64 size) { // Helper function that performs the common sanity checks for svcMapMemory // and svcUnmapMemory. This is doable, as both functions perform their sanitizing // in the same order. -Result MapUnmapMemorySanityChecks(const KProcessPageTable& manager, u64 dst_addr, u64 src_addr, - u64 size) { - if (!Common::Is4KBAligned(dst_addr)) { +Result MapUnmapMemorySanityChecks(const KProcessPageTable& manager, u64 dst_addr, u64 src_addr, u64 size) { + if (!Common::IsAligned(dst_addr, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); R_THROW(ResultInvalidAddress); } - if (!Common::Is4KBAligned(src_addr)) { + if (!Common::IsAligned(src_addr, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Source address is not aligned to 4KB, 0x{:016X}", src_addr); R_THROW(ResultInvalidSize); } @@ -49,7 +48,7 @@ Result MapUnmapMemorySanityChecks(const KProcessPageTable& manager, u64 dst_addr R_THROW(ResultInvalidSize); } - if (!Common::Is4KBAligned(size)) { + if (!Common::IsAligned(size, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:016X}", size); R_THROW(ResultInvalidSize); } diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp index facf8ee638..8fbb0da34f 100644 --- a/src/core/hle/kernel/svc/svc_physical_memory.cpp +++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -33,12 +33,12 @@ Result SetHeapSize(Core::System& system, u64* out_address, u64 size) { Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size={:#X}", addr, size); - if (!Common::Is4KBAligned(addr)) { + if (!Common::IsAligned(addr, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr); R_THROW(ResultInvalidAddress); } - if (!Common::Is4KBAligned(size)) { + if (!Common::IsAligned(size, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, {:#X}", size); R_THROW(ResultInvalidSize); } @@ -82,12 +82,12 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size={:#X}", addr, size); - if (!Common::Is4KBAligned(addr)) { + if (!Common::IsAligned(addr, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr); R_THROW(ResultInvalidAddress); } - if (!Common::Is4KBAligned(size)) { + if (!Common::IsAligned(size, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, {:#X}", size); R_THROW(ResultInvalidSize); } diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp index 0c18be91ba..846e0a0ebf 100644 --- a/src/core/hle/kernel/svc/svc_process_memory.cpp +++ b/src/core/hle/kernel/svc/svc_process_memory.cpp @@ -140,19 +140,19 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst "src_address=0x{:016X}, size=0x{:016X}", process_handle, dst_address, src_address, size); - if (!Common::Is4KBAligned(src_address)) { + if (!Common::IsAligned(src_address, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", src_address); R_THROW(ResultInvalidAddress); } - if (!Common::Is4KBAligned(dst_address)) { + if (!Common::IsAligned(dst_address, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", dst_address); R_THROW(ResultInvalidAddress); } - if (size == 0 || !Common::Is4KBAligned(size)) { + if (size == 0 || !Common::IsAligned(size, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X})", size); R_THROW(ResultInvalidSize); } @@ -190,6 +190,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst R_THROW(ResultInvalidCurrentMemory); } + R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState::AliasCode), ResultInvalidCurrentMemory); R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); } @@ -200,19 +201,19 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d "size=0x{:016X}", process_handle, dst_address, src_address, size); - if (!Common::Is4KBAligned(dst_address)) { + if (!Common::IsAligned(dst_address, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", dst_address); R_THROW(ResultInvalidAddress); } - if (!Common::Is4KBAligned(src_address)) { + if (!Common::IsAligned(src_address, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", src_address); R_THROW(ResultInvalidAddress); } - if (size == 0 || !Common::Is4KBAligned(size)) { + if (size == 0 || !Common::IsAligned(size, Core::Memory::YUZU_PAGESIZE)) { LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X}).", size); R_THROW(ResultInvalidSize); } @@ -250,6 +251,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d R_THROW(ResultInvalidCurrentMemory); } + R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState::AliasCode), ResultInvalidCurrentMemory); R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size)); }