gpulib: fix out-of-bounds reads in do_cmd_buffer()
authorDaniel Silsby <dansilsby@gmail.com>
Sat, 9 Nov 2019 01:30:04 +0000 (20:30 -0500)
committertwinaphex <libretro@gmail.com>
Sat, 8 Feb 2020 14:50:06 +0000 (15:50 +0100)
When gpu.cmd_buffer[] is filling up, and the last 1 or 2 words
in it are the beginning of a new vram read/write cmd, do_cmd_buffer()
would access out-of-bounds, reading garbage pos/size data.

Fixes corrupted gfx in this PS1 .exe test utility:
https://github.com/PeterLemon/PSX/tree/master/CPUTest/CPU/LOADSTORE/LW
(This and all similar tests on Peter's site).
Note that gfx access in this utility is done entirely through cmds given
through GPUwriteData(), i.e. direct CPU->GP0 stores, not DMA.

plugins/gpulib/gpu.c

index 17386b4..007da65 100644 (file)
@@ -528,6 +528,12 @@ static noinline int do_cmd_buffer(uint32_t *data, int count)
 
     cmd = data[pos] >> 24;
     if (0xa0 <= cmd && cmd <= 0xdf) {
+      if (unlikely((pos+2) >= count)) {
+        // incomplete vram write/read cmd, can't consume yet
+        cmd = -1;
+        break;
+      }
+
       // consume vram write/read cmd
       start_vram_transfer(data[pos + 1], data[pos + 2], (cmd & 0xe0) == 0xc0);
       pos += 3;