Fix various possible OOB read/writes in mupen64plus

fixes #3929
This commit is contained in:
CasualPokePlayer 2024-05-29 22:38:53 -07:00
parent 7e6e9705ae
commit e7c093eac6
7 changed files with 83 additions and 53 deletions

Binary file not shown.

View File

@ -60,8 +60,8 @@ void DebugMessage(int level, const char *message, ...)
if(level == M64MSG_ERROR)
{
//trigger a vsync just to get out of frame advance
new_vi();
//trigger a vsync just to get out of frame advance
new_vi();
WaitForSingleObject(rompausesem, INFINITE);
}

View File

@ -106,8 +106,8 @@ void dma_pi_read(void)
{
for (i=0; i < (pi_register.pi_rd_len_reg & 0xFFFFFF)+1; i++)
{
sram[((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8] =
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8];
sram[MASK_ADDR_U8(((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8, sram)] =
((unsigned char*)rdram)[MASK_ADDR_U8((pi_register.pi_dram_addr_reg+i)^S8, rdram)];
}
sram_write_file();
@ -145,8 +145,8 @@ void dma_pi_write(void)
for (i=0; i<(int)(pi_register.pi_wr_len_reg & 0xFFFFFF)+1; i++)
{
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
sram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8];
((unsigned char*)rdram)[MASK_ADDR_U8((pi_register.pi_dram_addr_reg+i)^S8, rdram)]=
sram[MASK_ADDR_U8((((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8, sram)];
}
flashram_info.use_flashram = -1;
@ -204,8 +204,8 @@ void dma_pi_write(void)
unsigned long rdram_address1 = pi_register.pi_dram_addr_reg+i+0x80000000;
unsigned long rdram_address2 = pi_register.pi_dram_addr_reg+i+0xa0000000;
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8];
((unsigned char*)rdram)[MASK_ADDR_U8((pi_register.pi_dram_addr_reg+i)^S8, rdram)]=
rom[MASK_ADDR_U8((((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8, rom)];
if (!invalid_code[rdram_address1>>12])
{
@ -234,8 +234,8 @@ void dma_pi_write(void)
{
for (i=0; i<(int)longueur; i++)
{
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8];
((unsigned char*)rdram)[MASK_ADDR_U8((pi_register.pi_dram_addr_reg+i)^S8, rdram)]=
rom[MASK_ADDR_U8((((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8, rom)];
}
}
@ -300,7 +300,7 @@ void dma_sp_write(void)
for(j=0; j<count; j++) {
for(i=0; i<length; i++) {
spmem[memaddr^S8] = dram[dramaddr^S8];
spmem[MASK_ADDR_U8(memaddr^S8, SP_DMEM)] = dram[MASK_ADDR_U8(dramaddr^S8, rdram)];
memaddr++;
dramaddr++;
}
@ -326,7 +326,7 @@ void dma_sp_read(void)
for(j=0; j<count; j++) {
for(i=0; i<length; i++) {
dram[dramaddr^S8] = spmem[memaddr^S8];
dram[MASK_ADDR_U8(dramaddr^S8, rdram)] = spmem[MASK_ADDR_U8(memaddr^S8, SP_DMEM)];
memaddr++;
dramaddr++;
}
@ -345,7 +345,7 @@ void dma_si_write(void)
for (i=0; i<(64/4); i++)
{
PIF_RAM[i] = sl(rdram[si_register.si_dram_addr/4+i]);
PIF_RAM[i] = sl(rdram[MASK_ADDR_U32(si_register.si_dram_addr/4+i, rdram)]);
}
update_pif_write();
@ -366,7 +366,7 @@ void dma_si_read(void)
for (i=0; i<(64/4); i++)
{
rdram[si_register.si_dram_addr/4+i] = sl(PIF_RAM[i]);
rdram[MASK_ADDR_U32(si_register.si_dram_addr/4+i, rdram)] = sl(PIF_RAM[i]);
}
update_count();

View File

@ -135,7 +135,7 @@ void flashram_command(unsigned int command)
unsigned int i;
for (i=flashram_info.erase_offset; i<(flashram_info.erase_offset+128); i++)
{
flashram[i^S8] = 0xff;
flashram[MASK_ADDR_U8(i^S8, flashram)] = 0xff;
}
flashram_write_file();
}
@ -145,8 +145,8 @@ void flashram_command(unsigned int command)
int i;
for (i=0; i<128; i++)
{
flashram[(flashram_info.erase_offset+i)^S8]=
((unsigned char*)rdram)[(flashram_info.write_pointer+i)^S8];
flashram[MASK_ADDR_U8((flashram_info.erase_offset+i)^S8, flashram)]=
((unsigned char*)rdram)[MASK_ADDR_U8((flashram_info.write_pointer+i)^S8, rdram)];
}
flashram_write_file();
}
@ -180,14 +180,14 @@ void dma_read_flashram(void)
switch (flashram_info.mode)
{
case STATUS_MODE:
rdram[pi_register.pi_dram_addr_reg/4] = (unsigned int)(flashram_info.status >> 32);
rdram[pi_register.pi_dram_addr_reg/4+1] = (unsigned int)(flashram_info.status);
rdram[MASK_ADDR_U32(pi_register.pi_dram_addr_reg/4, rdram)] = (unsigned int)(flashram_info.status >> 32);
rdram[MASK_ADDR_U32(pi_register.pi_dram_addr_reg/4+1, rdram)] = (unsigned int)(flashram_info.status);
break;
case READ_MODE:
for (i=0; i<(pi_register.pi_wr_len_reg & 0x0FFFFFF)+1; i++)
{
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
flashram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)*2+i)^S8];
((unsigned char*)rdram)[MASK_ADDR_U8((pi_register.pi_dram_addr_reg+i)^S8, rdram)]=
flashram[MASK_ADDR_U8((((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)*2+i)^S8, rdram)];
}
break;
default:

View File

@ -26,6 +26,9 @@
#define TRACECB() if (traceCB) traceCB()
#define MASK_ADDR_U8(x, m) (x) & (sizeof(m) - 1)
#define MASK_ADDR_U32(x, m) (x) & (sizeof(m) / 4 - 1)
int init_memory(int DoByteSwap);
void free_memory(void);
#define read_word_in_memory() readmem[address>>16]()

View File

@ -91,7 +91,7 @@ static void eeprom_write_file(void)
free(filename);*/
saveramModified = 1;
saveramModified = 1;
}
/*static char *get_mempack_path(void)
@ -169,7 +169,7 @@ static void mempack_write_file(void)
free(filename);*/
saveramModified = 1;
saveramModified = 1;
}
//#define DEBUG_PIF
@ -302,15 +302,17 @@ static unsigned char mempack_crc(unsigned char *data)
return CRC;
}
static void internal_ReadController(int Control, unsigned char *Command)
static void internal_ReadController(int Control, unsigned char *Command, unsigned int Remaining)
{
if (Remaining <= 2) return;
switch (Command[2])
{
case 1:
#ifdef DEBUG_PIF
DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 1 read buttons", Control);
#endif
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 6)
{
BUTTONS Keys;
input.getKeys(Control, &Keys);
@ -324,7 +326,7 @@ static void internal_ReadController(int Control, unsigned char *Command)
#ifdef DEBUG_PIF
DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 2 read controller pack (in Input plugin)", Control);
#endif
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 37)
{
if (Controls[Control].Plugin == PLUGIN_RAW)
if (input.readController)
@ -335,7 +337,7 @@ static void internal_ReadController(int Control, unsigned char *Command)
#ifdef DEBUG_PIF
DebugMessage(M64MSG_INFO, "internal_ReadController() Channel %i Command 3 write controller pack (in Input plugin)", Control);
#endif
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 37)
{
if (Controls[Control].Plugin == PLUGIN_RAW)
if (input.readController)
@ -345,8 +347,10 @@ static void internal_ReadController(int Control, unsigned char *Command)
}
}
static void internal_ControllerCommand(int Control, unsigned char *Command)
static void internal_ControllerCommand(int Control, unsigned char *Command, unsigned int Remaining)
{
if (Remaining <= 2) return;
switch (Command[2])
{
case 0x00: // read status
@ -356,7 +360,7 @@ static void internal_ControllerCommand(int Control, unsigned char *Command)
#ifdef DEBUG_PIF
DebugMessage(M64MSG_INFO, "internal_ControllerCommand() Channel %i Command %02x check pack present", Control, Command[2]);
#endif
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 5)
{
Command[3] = 0x05;
Command[4] = 0x00;
@ -384,7 +388,7 @@ static void internal_ControllerCommand(int Control, unsigned char *Command)
Command[1] |= 0x80;
break;
case 0x02: // read controller pack
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 0x25)
{
switch (Controls[Control].Plugin)
{
@ -434,7 +438,7 @@ static void internal_ControllerCommand(int Control, unsigned char *Command)
Command[1] |= 0x80;
break;
case 0x03: // write controller pack
if (Controls[Control].Present)
if (Controls[Control].Present && Remaining > 0x25)
{
switch (Controls[Control].Plugin)
{
@ -539,7 +543,7 @@ void update_pif_write(void)
Controls[channel].RawData)
input.controllerCommand(channel, &PIF_RAMb[i]);
else
internal_ControllerCommand(channel, &PIF_RAMb[i]);
internal_ControllerCommand(channel, &PIF_RAMb[i], 0x40 - i);
}
else if (channel == 4)
EepromCommand(&PIF_RAMb[i]);
@ -583,10 +587,33 @@ void update_pif_read(void)
if (channel < 4)
{
if (Controls[channel].Present &&
Controls[channel].RawData)
input.readController(channel, &PIF_RAMb[i]);
Controls[channel].RawData)
{
unsigned int remaining = 0x40 - i;
unsigned int needed = 3;
if (remaining > 2)
{
switch (PIF_RAMb[i + 2])
{
case 0x00:
case 0xFF:
needed = 6;
break;
case 0x01:
needed = 7;
break;
case 0x02:
case 0x03:
needed = 38;
break;
}
}
if (remaining >= needed)
input.readController(channel, &PIF_RAMb[i]);
}
else
internal_ReadController(channel, &PIF_RAMb[i]);
internal_ReadController(channel, &PIF_RAMb[i], 0x40 - i);
}
i += PIF_RAMb[i] + (PIF_RAMb[(i+1)] & 0x3F) + 1;
channel++;
@ -601,27 +628,27 @@ void update_pif_read(void)
EXPORT void CALL init_saveram(void)
{
eeprom_format();
mempack_format();
saveramModified = 0;
eeprom_format();
mempack_format();
saveramModified = 0;
flashram_format();
flashram_format();
sram_format();
sram_format();
}
EXPORT void CALL save_saveram(unsigned char * dest)
{
memcpy(dest, eeprom, 0x800);
memcpy(dest + 0x800, mempack, 4 * 0x8000);
memcpy(dest + (0x800 + 4 * 0x8000), flashram, 0x20000);
memcpy(dest + (0x800 + 4 * 0x8000 + 0x20000), sram, 0x8000);
memcpy(dest, eeprom, 0x800);
memcpy(dest + 0x800, mempack, 4 * 0x8000);
memcpy(dest + (0x800 + 4 * 0x8000), flashram, 0x20000);
memcpy(dest + (0x800 + 4 * 0x8000 + 0x20000), sram, 0x8000);
}
EXPORT void CALL load_saveram(unsigned char * src)
{
memcpy(eeprom, src, 0x800);
memcpy(mempack, src + 0x800, 4 * 0x8000);
memcpy(flashram, src + (0x800 + 4 * 0x8000), 0x20000);
memcpy(sram, src + (0x800 + 4 * 0x8000 + 0x20000), 0x8000);
memcpy(eeprom, src, 0x800);
memcpy(mempack, src + 0x800, 4 * 0x8000);
memcpy(flashram, src + (0x800 + 4 * 0x8000), 0x20000);
memcpy(sram, src + (0x800 + 4 * 0x8000 + 0x20000), 0x8000);
}

View File

@ -127,7 +127,7 @@ void add_interupt_event(int type, unsigned int delay)
if (get_event(type)) {
DebugMessage(M64MSG_WARNING, "two events of type 0x%x in interrupt queue", type);
return;
return;
}
if (q == NULL)
@ -384,7 +384,7 @@ void gen_interupt(void)
#ifdef WITH_LIRC
lircCheckInput();
#endif
SDL_PumpEvents();
//SDL_PumpEvents();
refresh_stat();
@ -397,7 +397,7 @@ void gen_interupt(void)
// {
//SDL_Delay(10);
SDL_PumpEvents();
//SDL_PumpEvents();
#ifdef WITH_LIRC
lircCheckInput();
#endif //WITH_LIRC
@ -405,7 +405,7 @@ void gen_interupt(void)
//}
new_vi();
WaitForSingleObject(rompausesem, INFINITE);
WaitForSingleObject(rompausesem, INFINITE);
if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
next_vi += vi_register.vi_delay;
@ -443,7 +443,7 @@ void gen_interupt(void)
#ifdef WITH_LIRC
lircCheckInput();
#endif //WITH_LIRC
SDL_PumpEvents();
//SDL_PumpEvents();
PIF_RAMb[0x3F] = 0x0;
remove_interupt_event();
MI_register.mi_intr_reg |= 0x02;