From dd4df5fbca7251a1e3e8a3ae51c49ace4776074b Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Tue, 6 Oct 2026 09:38:47 +0000 Subject: [PATCH] fix some memory offset checks (#1243) --- parallel-rdp/interface.cpp | 8 ++++++-- parallel-rdp/interface.hpp | 2 +- retroachievements/retroachievements.c | 2 +- src/savestates.rs | 2 +- src/ui/video.rs | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/parallel-rdp/interface.cpp b/parallel-rdp/interface.cpp index df2f2895..0e57f338 100644 --- a/parallel-rdp/interface.cpp +++ b/parallel-rdp/interface.cpp @@ -779,8 +779,12 @@ void rdp_save_state(uint8_t *state) { } } -void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state) { +void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state, + size_t state_size) { gfx_info = _gfx_info; + if (state_size < rdp_state_size()) { + return; + } memcpy(&rdp_device, state, sizeof(RDP_DEVICE)); if (g_tmem) { @@ -852,7 +856,7 @@ uint64_t rdp_process_commands() { return interrupt_timer; } else { do { - offset &= 0xFFFFF8; + offset &= (gfx_info.RDRAM_SIZE - 1) & ~uint32_t(7); rdp_device.cmd_data[2 * rdp_device.cmd_ptr + 0] = *reinterpret_cast(gfx_info.RDRAM + offset); rdp_device.cmd_data[2 * rdp_device.cmd_ptr + 1] = diff --git a/parallel-rdp/interface.hpp b/parallel-rdp/interface.hpp index 8fe9274b..db2062d1 100644 --- a/parallel-rdp/interface.hpp +++ b/parallel-rdp/interface.hpp @@ -65,7 +65,7 @@ void rdp_onscreen_message(const char *message, MESSAGE_LENGTH milliseconds); void rdp_check_framebuffers(uint32_t address, uint32_t length); size_t rdp_state_size(); void rdp_save_state(uint8_t *state); -void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state); +void rdp_load_state(GFX_INFO _gfx_info, const uint8_t *state, size_t state_size); void rdp_set_fps(uint32_t fps, uint32_t vis); JoystickEvent get_joystick_event(); diff --git a/retroachievements/retroachievements.c b/retroachievements/retroachievements.c index e52723dd..594dc87e 100644 --- a/retroachievements/retroachievements.c +++ b/retroachievements/retroachievements.c @@ -26,7 +26,7 @@ static char g_rich_presence_buffer[512]; static uint32_t read_memory(uint32_t address, uint8_t *buffer, uint32_t num_bytes, rc_client_t *client) { - if (address + num_bytes > g_rdram_size) + if (num_bytes > g_rdram_size || address > g_rdram_size - num_bytes) memset(buffer, 0, num_bytes); else memcpy(buffer, &g_rdram[address], num_bytes); diff --git a/src/savestates.rs b/src/savestates.rs index 21cf91fc..19342da7 100644 --- a/src/savestates.rs +++ b/src/savestates.rs @@ -348,7 +348,7 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool, rewind_frame: O } ui::audio::update_freq(device); - ui::video::load_state(device, state.rdp_state.as_ptr()); + ui::video::load_state(device, state.rdp_state.as_ptr(), state.rdp_state.len()); if !state.ra_state.is_empty() { retroachievements::load_state(state.ra_state.as_ptr(), state.ra_state.len()); diff --git a/src/ui/video.rs b/src/ui/video.rs index 4874dc49..62ad5b30 100644 --- a/src/ui/video.rs +++ b/src/ui/video.rs @@ -192,10 +192,10 @@ pub fn idle() { unsafe { rdp_idle() } } -pub fn load_state(device: &mut device::Device, rdp_state: *const u8) { +pub fn load_state(device: &mut device::Device, rdp_state: *const u8, rdp_state_len: usize) { let gfx_info = build_gfx_info(device, device.netplay.is_some()); unsafe { - rdp_load_state(gfx_info, rdp_state); + rdp_load_state(gfx_info, rdp_state, rdp_state_len); for reg in 0..device::vi::VI_REGS_COUNT { rdp_set_vi_register(reg as u32, device.vi.regs[reg]) }