diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2022-04-18 04:13:25 +0200 |
|---|---|---|
| committer | Admiral H. Curtiss <pikachu025@gmail.com> | 2022-04-18 23:48:00 +0200 |
| commit | ef760ee012a1a7a9d8997fecce4f0c9a7122e1bd (patch) | |
| tree | 1e97fada9f3c2a759a5d6b78353fee2ad051385b /Source/Core/Common/ChunkFile.h | |
| parent | 853cf4f8181dd0162e81ebcd61331d8765d089ca (diff) | |
Common/PointerWrap: Prevent reads/writes past the end of the buffer.
Diffstat (limited to 'Source/Core/Common/ChunkFile.h')
| -rw-r--r-- | Source/Core/Common/ChunkFile.h | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/Source/Core/Common/ChunkFile.h b/Source/Core/Common/ChunkFile.h index e7791839db..9fd785459e 100644 --- a/Source/Core/Common/ChunkFile.h +++ b/Source/Core/Common/ChunkFile.h @@ -47,11 +47,16 @@ public: }; private: - u8** ptr; + u8** m_ptr_current; + u8* m_ptr_end; Mode mode; public: - PointerWrap(u8** ptr_, Mode mode_) : ptr(ptr_), mode(mode_) {} + PointerWrap(u8** ptr, size_t size, Mode mode_) + : m_ptr_current(ptr), m_ptr_end(*ptr + size), mode(mode_) + { + } + void SetMode(Mode mode_) { mode = mode_; } Mode GetMode() const { return mode; } template <typename K, class V> @@ -209,8 +214,13 @@ public: [[nodiscard]] u8* DoExternal(u32& count) { Do(count); - u8* current = *ptr; - *ptr += count; + u8* current = *m_ptr_current; + *m_ptr_current += count; + if (mode != MODE_MEASURE && *m_ptr_current > m_ptr_end) + { + // trying to read/write past the end of the buffer, prevent this + mode = MODE_MEASURE; + } return current; } @@ -320,26 +330,32 @@ private: DOLPHIN_FORCE_INLINE void DoVoid(void* data, u32 size) { + if (mode != MODE_MEASURE && (*m_ptr_current + size) > m_ptr_end) + { + // trying to read/write past the end of the buffer, prevent this + mode = MODE_MEASURE; + } + switch (mode) { case MODE_READ: - memcpy(data, *ptr, size); + memcpy(data, *m_ptr_current, size); break; case MODE_WRITE: - memcpy(*ptr, data, size); + memcpy(*m_ptr_current, data, size); break; case MODE_MEASURE: break; case MODE_VERIFY: - DEBUG_ASSERT_MSG(COMMON, !memcmp(data, *ptr, size), + DEBUG_ASSERT_MSG(COMMON, !memcmp(data, *m_ptr_current, size), "Savestate verification failure: buf {} != {} (size {}).\n", fmt::ptr(data), - fmt::ptr(*ptr), size); + fmt::ptr(*m_ptr_current), size); break; } - *ptr += size; + *m_ptr_current += size; } }; |
