diff mbox series

[2/2] floppy: add a regression test for CVE-2021-20196

Message ID 20210319050906.14875-2-alxndr@bu.edu (mailing list archive)
State New, archived
Headers show
Series [1/2] floppy: add a regression test for CVE-2020-25741 | expand

Commit Message

Alexander Bulekov March 19, 2021, 5:09 a.m. UTC
dd if=/dev/zero of=/tmp/fda.img bs=1024 count=1440
cat << EOF | ./qemu-system-i386 -nographic -m 512M -nodefaults \
-accel qtest -fda /tmp/fda.img -qtest stdio
outw 0x3f4 0x0500
outb 0x3f5 0x00
outb 0x3f5 0x00
outw 0x3f4 0x00
outb 0x3f5 0x00
outw 0x3f1 0x0400
outw 0x3f4 0x0
outw 0x3f4 0x00
outb 0x3f5 0x0
outb 0x3f5 0x01
outw 0x3f1 0x0500
outb 0x3f5 0x00
EOF

Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
---

Since this looks very similar to CVE-2021-20196 (I believe Li pointed
out that issue in this thread), I'm also posting the reproducer for that
here.

 tests/qtest/fuzz-test.c | 57 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
diff mbox series

Patch

diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index 62ececc66f..8e4ccdaca8 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -76,6 +76,61 @@  static void test_fdc_cve_2020_25741(void)
     qtest_quit(s);
 }
 
+
+/*
+ * ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000344
+ * The signal is caused by a WRITE memory access.
+ * #0 0x555556494543 in blk_inc_in_flight /block/block-backend.c:1356:5
+ * #1 0x555556494543 in blk_prw /block/block-backend.c:1328:5
+ * #2 0x555556494d03 in blk_pread /block/block-backend.c:1491:15
+ * #3 0x555555ec8986 in fdctrl_read_data /hw/block/fdc.c:1910:17
+ * #4 0x555555ec8986 in fdctrl_read /hw/block/fdc.c:936:18
+ * #5 0x5555563f26b7 in portio_read /softmmu/ioport.c:185:25
+ * #6 0x55555636908a in memory_region_read_accessor /softmmu/memory.c:442:11
+ * #7 0x55555635ec25 in access_with_adjusted_size /softmmu/memory.c:552:18
+ * #8 0x55555635ec25 in memory_region_dispatch_read1 /softmmu/memory.c:1420:16
+ * #9 0x55555635ec25 in memory_region_dispatch_read /softmmu/memory.c:1448:9
+ * #10 0x555556248aa7 in flatview_read_continue /softmmu/physmem.c:2810:23
+ * #11 0x5555563f18f0 in address_space_read /include/exec/memory.h:2494:26
+ * #12 0x5555563f18f0 in cpu_inw /softmmu/ioport.c:99:5
+ * #13 0x55555637619c in qtest_process_command /softmmu/qtest.c:502:21
+ * #14 0x55555637535d in qtest_process_inbuf /softmmu/qtest.c:797:9
+ * #15 0x555556405f9c in tcp_chr_read /chardev/char-socket.c:557:13
+ * #16 0x7ffff6f8ac3e in g_main_context_dispatch
+ * #17 0x5555567479f1 in glib_pollfds_poll /util/main-loop.c:231:9
+ * #18 0x5555567479f1 in os_host_main_loop_wait /util/main-loop.c:254:5
+ * #19 0x5555567479f1 in main_loop_wait /util/main-loop.c:530:11
+ * #20 0x5555562d9ee4 in qemu_main_loop /softmmu/runstate.c:725:9
+ * #21 0x555555d5b615 in main /softmmu/main.c:50:5
+*/
+static void test_fdc_cve_2021_20196(void)
+{
+    QTestState *s;
+    int fd;
+    char tmpdisk[] = "/tmp/fda.XXXXXX";
+    fd = mkstemp(tmpdisk);
+    assert(fd >= 0);
+    ftruncate(fd, 1440 * 1024);
+    close(fd);
+
+    s = qtest_initf("-nographic -m 512M -nodefaults "
+                    "-drive file=%s,format=raw,if=floppy", tmpdisk);
+    qtest_outw(s, 0x3f2, 0x04);
+    qtest_outw(s, 0x3f4, 0x0200);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f4, 0x00);
+    qtest_outw(s, 0x3f2, 0x01);
+    qtest_inw(s, 0x3f4);
+    qtest_quit(s);
+    unlink(tmpdisk);
+}
+
 int main(int argc, char **argv)
 {
     const char *arch = qtest_get_arch();
@@ -87,6 +142,8 @@  int main(int argc, char **argv)
                        test_lp1878642_pci_bus_get_irq_level_assert);
         qtest_add_func("fuzz/test_fdc_cve_2020_25741",
                        test_fdc_cve_2020_25741);
+        qtest_add_func("fuzz/test_fdc_cve_2021_20196",
+                       test_fdc_cve_2021_20196);
     }
 
     return g_test_run();