Sample files were attached to this issue in a ZIP file (s2.zip).
Issue 1 - OOB read past the end of itype array
Crash is reproducible only if mupen64plus-core lib was compiled with AddressSanitizer.
Loading and executing attached bug1.z64 file results in the following crash:
$ ./BinAsan/Release/RMG /tmp/bug1.z64
=================================================================
==185744==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fb32e8d0b60 at pc 0x7fb32ad7ce36 bp 0x7fb300a9cab0 sp 0x7fb300a9caa0
READ of size 1 at 0x7fb32e8d0b60 thread T13 (Thread::Emulati)
#0 0x7fb32ad7ce35 in address_generation /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:4379
#1 0x7fb32add0dc2 in new_recompile_block /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:11539
#2 0x7fb32ad6d338 in get_addr /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:2677
#3 0x7fb32ad6d5ea in get_addr_ht /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:2693
#4 0x7fb32add7f12 (/tmp/RMG/BinAsan/Release/Core/libmupen64plus.so+0x1d7f12) (BuildId: b6a0b16a4fee2ce372193dff1a7b713543d87145)
0x7fb32e8d0b60 is located 32 bytes before global variable 'opcode' defined in '/tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:247:15' (0x7fb32e8d0b80) of size 4096
0x7fb32e8d0b60 is located 0 bytes after global variable 'itype' defined in '/tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:246:15' (0x7fb32e8cfb60) of size 4096
SUMMARY: AddressSanitizer: global-buffer-overflow /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:4379 in address_generation
...
In presented case itype array index is 4096 (i+1=4096), but array size is only 4096 (so highest valid index is 4095). This leads to out-of-bounds read past the end of the itype array.
Issue 2 - OOB read past the end of LUT_r and LUT_w arrays
Loading and executing attached bug2a.z64 and bug2b.z64 files results in the following crashes:
$ gdb -ex run --args Bin/Release/RMG /tmp/bug2a.z64
GNU gdb (Ubuntu 13.1-2ubuntu2) 13.1
...
Thread 14 "Thread::Emulati" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffa63fd6c0 (LWP 186033)]
0x00007fffcc08ed4a in invalidate_block (block=3466518528) at /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:2816
2816 if(page>262143&&g_dev.r4300.cp0.tlb.LUT_r[block]) page=(g_dev.r4300.cp0.tlb.LUT_r[block]^0x80000000)>>12;
(gdb) print block
$1 = 3466518528
...
$ gdb -ex run --args Bin/Release/RMG /tmp/bug2b.z64
GNU gdb (Ubuntu 13.1-2ubuntu2) 13.1
...
Thread 14 "Thread::Emulati" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd23fd6c0 (LWP 186077)]
0x00007fffc808efac in invalidate_block (block=2433696) at /tmp/RMG/Source/3rdParty/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c:2874
2874 if(g_dev.r4300.cp0.tlb.LUT_w[block]) {
(gdb) print block
$1 = 2433696
In presented cases LUT_r and LUT_w arrays index (block) equals 3,466,518,528 or 2,433,696, but array size is only 1,048,576. This leads to out-of-bounds read past the end of the arrays and crash due to memory access violation.
Note: not sure, but it looks like g_dev.r4300.cached_interp.invalid_code access also leads to OOB read, though app doesn't crash there:
Sample files were attached to this issue in a ZIP file (s2.zip).
Issue 1 - OOB read past the end of
itype
arrayCrash is reproducible only if mupen64plus-core lib was compiled with AddressSanitizer.
Loading and executing attached
bug1.z64
file results in the following crash:Crash happens in:
https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/new_dynarec.c#L4379
In presented case
itype
array index is 4096 (i+1=4096
), but array size is only 4096 (so highest valid index is 4095). This leads to out-of-bounds read past the end of theitype
array.Issue 2 - OOB read past the end of
LUT_r
andLUT_w
arraysLoading and executing attached
bug2a.z64
andbug2b.z64
files results in the following crashes:Crash happens in one of these places:
https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/new_dynarec.c#L2816 https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/new_dynarec.c#L2874
In presented cases
LUT_r
andLUT_w
arrays index (block
) equals 3,466,518,528 or 2,433,696, but array size is only 1,048,576. This leads to out-of-bounds read past the end of the arrays and crash due to memory access violation.Note: not sure, but it looks like
g_dev.r4300.cached_interp.invalid_code
access also leads to OOB read, though app doesn't crash there:https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/new_dynarec.c#L2872
Issue 3 - OOB read of bytes placed before
invalidate_block_reg
arrayCrash is reproducible only if mupen64plus-core lib was compiled with AddressSanitizer.
Loading and executing attached
bug3.z64
file results in the following crash:Crash happens in:
https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/x64/assem_x64.c#L3032
In presented case
invalidate_block_reg
array index is -1. This leads to out-of-bounds read of bytes placed beforeinvalidate_block_reg
array.Please note that the similar issue may exist in related files too (e.g. assem_x86.c).
Issue 4 - NULL pointer dereference in set_jump_taget function
Loading and executing attached
bug4.z64
file results in the following crash:Crash happens in:
https://github.com/mupen64plus/mupen64plus-core/blob/f500eb58f76e636e231c3cc2b3d904210f0677c9/src/device/r4300/new_dynarec/x64/assem_x64.c#L73
In presented case
ptr
value is NULL, leading to NULL pointer dereference and crash. This issue does not seem to lead to any security issues.Please note that the similar issue may exist in related files too (e.g. assem_x86.c).
Test platform
CFLAGS += -O0 -g -fsanitize=address
-O0
and-g
for better crash backtraces in Release build-fsanitize=address
to compile with AddressSanitizer