From 9fab2c8d346bf89b8efdf4f98ac04510728c05cc Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Wed, 8 May 2024 20:07:25 +0200 Subject: [PATCH] Add out-of-bounds checking for register read/writes --- .../src/device/rcp/ai/ai_controller.c | 10 +++++++--- .../src/device/rcp/mi/mi_controller.c | 4 +++- .../src/device/rcp/pi/pi_controller.c | 4 +++- .../src/device/rcp/rdp/rdp_core.c | 16 ++++++++++++---- .../src/device/rcp/ri/ri_controller.c | 8 ++++++-- .../src/device/rcp/rsp/rsp_core.c | 16 ++++++++++++---- .../src/device/rcp/si/si_controller.c | 4 +++- .../src/device/rcp/vi/vi_controller.c | 8 ++++++-- .../mupen64plus-core/src/device/rdram/rdram.c | 6 +++++- 9 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ai/ai_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/ai/ai_controller.c index bc46a5f75..9e90cdbeb 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ai/ai_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ai/ai_controller.c @@ -180,7 +180,7 @@ void read_ai_regs(void* opaque, uint32_t address, uint32_t* value) ai->last_read = *value; } } - else + else if (reg < AI_REGS_COUNT) { *value = ai->regs[reg]; } @@ -212,11 +212,15 @@ void write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask if ((ai->regs[reg]) != (value & mask)) ai->samples_format_changed = 1; - masked_write(&ai->regs[reg], value, mask); + if (reg < AI_REGS_COUNT) { + masked_write(&ai->regs[reg], value, mask); + } return; } - masked_write(&ai->regs[reg], value, mask); + if (reg < AI_REGS_COUNT) { + masked_write(&ai->regs[reg], value, mask); + } } void ai_end_of_dma_event(void* opaque) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/mi/mi_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/mi/mi_controller.c index 05ecdd776..ed390eb99 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/mi/mi_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/mi/mi_controller.c @@ -83,7 +83,9 @@ void read_mi_regs(void* opaque, uint32_t address, uint32_t* value) struct mi_controller* mi = (struct mi_controller*)opaque; uint32_t reg = mi_reg(address); - *value = mi->regs[reg]; + if (reg < MI_REGS_COUNT) { + *value = mi->regs[reg]; + } } void write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/pi/pi_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/pi/pi_controller.c index 0fc36bf3d..6f8b0269c 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/pi/pi_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/pi/pi_controller.c @@ -209,7 +209,9 @@ void write_pi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask return; } - masked_write(&pi->regs[reg], value, mask); + if (reg < PI_REGS_COUNT) { + masked_write(&pi->regs[reg], value, mask); + } } void pi_end_of_dma_event(void* opaque) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/rdp/rdp_core.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/rdp/rdp_core.c index f091801bd..428652ed2 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/rdp/rdp_core.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/rdp/rdp_core.c @@ -86,7 +86,9 @@ void read_dpc_regs(void* opaque, uint32_t address, uint32_t* value) struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dpc_reg(address); - *value = dp->dpc_regs[reg]; + if (reg < DPC_REGS_COUNT) { + *value = dp->dpc_regs[reg]; + } } void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -106,7 +108,9 @@ void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas return; } - masked_write(&dp->dpc_regs[reg], value, mask); + if (reg < DPC_REGS_COUNT) { + masked_write(&dp->dpc_regs[reg], value, mask); + } switch(reg) { @@ -128,7 +132,9 @@ void read_dps_regs(void* opaque, uint32_t address, uint32_t* value) struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dps_reg(address); - *value = dp->dps_regs[reg]; + if (reg < DPS_REGS_COUNT) { + *value = dp->dps_regs[reg]; + } } void write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -136,7 +142,9 @@ void write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dps_reg(address); - masked_write(&dp->dps_regs[reg], value, mask); + if (reg < DPS_REGS_COUNT) { + masked_write(&dp->dps_regs[reg], value, mask); + } } void rdp_interrupt_event(void* opaque) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c index d74dd66c5..39ff36a84 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c @@ -41,7 +41,9 @@ void read_ri_regs(void* opaque, uint32_t address, uint32_t* value) struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = ri_reg(address); - *value = ri->regs[reg]; + if (reg < RI_REGS_COUNT) { + *value = ri->regs[reg]; + } } void write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -49,6 +51,8 @@ void write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = ri_reg(address); - masked_write(&ri->regs[reg], value, mask); + if (reg < RI_REGS_COUNT) { + masked_write(&ri->regs[reg], value, mask); + } } diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/rsp/rsp_core.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/rsp/rsp_core.c index 270fd6520..d6b4584d0 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/rsp/rsp_core.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/rsp/rsp_core.c @@ -259,7 +259,9 @@ void read_rsp_regs(void* opaque, uint32_t address, uint32_t* value) struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = rsp_reg(address); - *value = sp->regs[reg]; + if (reg < SP_REGS_COUNT) { + *value = sp->regs[reg]; + } if (reg == SP_SEMAPHORE_REG) { @@ -281,7 +283,9 @@ void write_rsp_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas return; } - masked_write(&sp->regs[reg], value, mask); + if (reg < SP_REGS_COUNT) { + masked_write(&sp->regs[reg], value, mask); + } switch(reg) { @@ -303,7 +307,9 @@ void read_rsp_regs2(void* opaque, uint32_t address, uint32_t* value) struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = rsp_reg2(address); - *value = sp->regs2[reg]; + if (reg < SP_REGS2_COUNT) { + *value = sp->regs2[reg]; + } if (reg == SP_PC_REG) *value &= 0xffc; @@ -318,7 +324,9 @@ void write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t ma if (reg == SP_PC_REG) mask &= 0xffc; - masked_write(&sp->regs2[reg], value, mask); + if (reg < SP_REGS2_COUNT) { + masked_write(&sp->regs2[reg], value, mask); + } } void do_SP_Task(struct rsp_core* sp) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/si/si_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/si/si_controller.c index c35de3745..5ef416627 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/si/si_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/si/si_controller.c @@ -123,7 +123,9 @@ void read_si_regs(void* opaque, uint32_t address, uint32_t* value) struct si_controller* si = (struct si_controller*)opaque; uint32_t reg = si_reg(address); - *value = si->regs[reg]; + if (reg < SI_REGS_COUNT) { + *value = si->regs[reg]; + } } void write_si_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/vi/vi_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/vi/vi_controller.c index 4cd3abb6a..e7eb8d4f2 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/vi/vi_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/vi/vi_controller.c @@ -105,7 +105,9 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value) vi->regs[VI_CURRENT_REG] = (vi->regs[VI_CURRENT_REG] & (~1)) | vi->field; } - *value = vi->regs[reg]; + if (reg < VI_REGS_COUNT) { + *value = vi->regs[reg]; + } } void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -151,7 +153,9 @@ void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask return; } - masked_write(&vi->regs[reg], value, mask); + if (reg < VI_REGS_COUNT) { + masked_write(&vi->regs[reg], value, mask); + } } void vi_vertical_interrupt_event(void* opaque) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c index 28065eaf0..7fbb20243 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c @@ -173,7 +173,9 @@ void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value) return; } - *value = rdram->regs[module][reg]; + if (reg < RDRAM_REGS_COUNT) { + *value = rdram->regs[module][reg]; + } /* some bits are inverted when read */ if (reg == RDRAM_MODE_REG) { @@ -211,6 +213,8 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m } } + /* don't go out-of-bounds */ + if (reg >= RDRAM_REGS_COUNT) return; if (address & RDRAM_BCAST_ADDRESS_MASK) { for (module = 0; module < modules; ++module) {