summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZephyron <zephyron@citron-emu.org>2025-02-08 19:32:06 +1000
committerZephyron <zephyron@citron-emu.org>2025-02-08 19:32:06 +1000
commit7ecb890a1613071bff317f468a15ead61eddf7a0 (patch)
tree1b94f8e37a819fe76d3c642682a5f4f33ddfa466
parentc31768ec15c75d4b8b3323b88fbc8c085dcb0041 (diff)
common: improve host memory mapping validation
- Add maximum memory size limit of 512GB (Overkill) - Implement additional safety checks for memory mapping: * Validate non-zero addresses * Verify address alignment * Add length validation against maximum size - Remove redundant assertion for host_offset alignment - Remove potentially problematic mapping verification - Improve error logging for invalid mapping attempts These changes enhance memory safety by adding proper bounds checking and validation before performing memory mappings, while removing a potentially problematic post-mapping verification step.
-rw-r--r--src/common/host_memory.cpp30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index ea1cdc612..0678efa50 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -41,6 +41,7 @@ namespace Common {
constexpr size_t PageAlignment = 0x1000;
constexpr size_t HugePageSize = 0x200000;
+constexpr size_t max_memory_size = 0x8000000000; // 512 GB max memory size
#ifdef _WIN32
@@ -112,7 +113,8 @@ public:
throw std::bad_alloc{};
}
// Allocate a virtual memory for the backing file map as placeholder
- backing_base = static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size,
+ backing_base =
+ static_cast<u8*>(pfn_VirtualAlloc2(process, nullptr, backing_size,
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
PAGE_NOACCESS, nullptr, 0));
if (!backing_base) {
@@ -743,23 +745,33 @@ HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default;
void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
MemoryPermission perms, bool separate_heap) {
+ // Add additional checks before mapping
+ if (virtual_offset == 0 || host_offset == 0) {
+ LOG_ERROR(Common_Memory, "Invalid memory mapping addresses");
+ return;
+ }
+
+ // Ensure addresses are properly aligned
+ if ((virtual_offset & 0xFFF) != 0 || (host_offset & 0xFFF) != 0) {
+ LOG_ERROR(Common_Memory, "Unaligned memory mapping addresses");
+ return;
+ }
+
+ // Add size validation
+ if (length == 0 || length > max_memory_size) {
+ LOG_ERROR(Common_Memory, "Invalid mapping length: {}", length);
+ return;
+ }
+
ASSERT(virtual_offset % PageAlignment == 0);
- ASSERT(host_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
- ASSERT(host_offset + length <= backing_size);
if (length == 0 || !virtual_base || !impl) {
return;
}
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
-
- // Verify mapping was successful
- if (!impl->IsValidMapping(virtual_offset + virtual_base_offset, length)) {
- LOG_CRITICAL(Common_Memory, "Failed to verify memory mapping: virtual_offset={:x}, host_offset={:x}, length={:x}",
- virtual_offset, host_offset, length);
- }
}
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {