diff options
author | Zephyron <zephyron@citron-emu.org> | 2025-02-01 21:50:33 +1000 |
---|---|---|
committer | Zephyron <zephyron@citron-emu.org> | 2025-02-01 21:50:33 +1000 |
commit | f4b9e54b2280eea66fe449416251d6c50ce0d3a8 (patch) | |
tree | 7ebe3e8a57efada717ac6bce4fe7f99628dfc313 | |
parent | 70a9f20ae11aee144bae229a81418cfaadf354f7 (diff) |
common/nvdrv: improve memory validation and error handling
Implements several improvements to memory handling and validation:
- host_memory: Add IsValidMapping() and IsDirectMappingEnabled() methods to
validate memory access
- host_memory: Fix virtual base offset calculation to use proper pointer
arithmetic
- host_memory: Add size field to track allocation size
- nvhost_ctrl_gpu: Return InvalidState instead of InvalidValue for TPC mask
buffer size validation
- Update copyright year for citron
The changes improve memory safety by adding explicit validation checks and
fixing pointer arithmetic in the virtual memory implementation.
-rw-r--r-- | src/common/host_memory.cpp | 29 | ||||
-rw-r--r-- | src/common/host_memory.h | 3 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 2 |
3 files changed, 32 insertions, 2 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 4f5a11f86..4ae22fcfb 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -200,11 +200,20 @@ public: UNREACHABLE(); } + bool IsValidMapping(size_t offset, size_t size) const { + return (offset + size) <= backing_size; + } + + bool IsDirectMappingEnabled() const { + return direct_mapping_enabled; + } + const size_t backing_size; ///< Size of the backing memory in bytes const size_t virtual_size; ///< Size of the virtual address placeholder in bytes u8* backing_base{}; u8* virtual_base{}; + bool direct_mapping_enabled{false}; private: /// Release all resources in the object @@ -602,6 +611,14 @@ public: virtual_base = nullptr; } + bool IsValidMapping(size_t offset, size_t size) const { + return (offset + size) <= backing_size; + } + + bool IsDirectMappingEnabled() const { + return virtual_base == nullptr; + } + const size_t backing_size; ///< Size of the backing memory in bytes const size_t virtual_size; ///< Size of the virtual address placeholder in bytes @@ -675,6 +692,14 @@ public: void EnableDirectMappedAddress() {} + bool IsValidMapping(size_t offset, size_t size) const { + return false; + } + + bool IsDirectMappingEnabled() const { + return false; + } + u8* backing_base{nullptr}; u8* virtual_base{nullptr}; }; @@ -696,7 +721,9 @@ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) // Ensure the virtual base is aligned to the L2 block size. virtual_base = reinterpret_cast<u8*>( Common::AlignUp(reinterpret_cast<uintptr_t>(virtual_base), HugePageSize)); - virtual_base_offset = virtual_base - impl->virtual_base; + virtual_base_offset = static_cast<size_t>( + reinterpret_cast<uintptr_t>(virtual_base) - + reinterpret_cast<uintptr_t>(impl->virtual_base)); } } catch (const std::bad_alloc&) { diff --git a/src/common/host_memory.h b/src/common/host_memory.h index 72fbb05af..7d4a94123 100644 --- a/src/common/host_memory.h +++ b/src/common/host_memory.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -82,6 +83,8 @@ private: // Fallback if fastmem is not supported on this platform std::unique_ptr<Common::VirtualBuffer<u8>> fallback_buffer; + + size_t size; }; } // namespace Common diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index bbf77c5ad..a83cc6b6a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -270,7 +270,7 @@ NvResult nvhost_ctrl_gpu::GetTpcMasks2(IoctlGetTpcMasks& params) { // Validate input parameters if (params.mask_buf_size == 0 || params.mask_buf_size > params.tpc_mask_buf.size()) { LOG_ERROR(Service_NVDRV, "Invalid mask buffer size {}", params.mask_buf_size); - return NvResult::InvalidValue; + return NvResult::InvalidState; } // Set up TPC mask values based on GPU configuration |