summary refs log tree commit diff stats
path: root/results/classifier/118/hypervisor/1919036
blob: a3cac68ba08844f14c03d24e401151c4cad6e56b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
hypervisor: 0.822
risc-v: 0.787
KVM: 0.736
mistranslation: 0.729
peripherals: 0.728
user-level: 0.724
ppc: 0.712
i386: 0.701
x86: 0.700
graphic: 0.689
TCG: 0.677
performance: 0.657
virtual: 0.655
VMM: 0.654
register: 0.650
vnc: 0.633
permissions: 0.618
device: 0.608
semantic: 0.584
architecture: 0.577
files: 0.547
arm: 0.533
assembly: 0.523
boot: 0.491
socket: 0.489
PID: 0.488
kernel: 0.479
network: 0.477
debug: 0.472

Assertion failure in fifo8_push_all() through am53c974

Hello,

Using hypervisor fuzzer, hyfuzz, I found an assertion failure through am53c974 emulator.

A malicious guest user/process could use this flaw to abort the QEMU process on the host, resulting in a denial of service.

This was found in version 5.2.0 (master, 3f8d1885e4)


```
qemu-system-i386: ../util/fifo8.c:43: fifo8_push_all: Assertion `fifo->num + num <= fifo->capacity' failed.

#0  0x00007ffff0218fb7 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff021a921 in __GI_abort () at abort.c:79
#2  0x00007ffff020a48a in __assert_fail_base (fmt=0x7ffff0391750 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x555558ed2400 "fifo->num + num <= fifo->capacity", file=file@entry=0x555558ed2380 "../util/fifo8.c", line=line@entry=0x2b, function=function@entry=0x555558ed2560 <__PRETTY_FUNCTION__.16583> "fifo8_push_all")
    at assert.c:92
#3  0x00007ffff020a502 in __GI___assert_fail (assertion=assertion@entry=0x555558ed2400 "fifo->num + num <= fifo->capacity", file=file@entry=0x555558ed2380 "../util/fifo8.c", line=line@entry=0x2b, function=function@entry=0x555558ed2560 <__PRETTY_FUNCTION__.16583> "fifo8_push_all") at assert.c:101
#4  0x00005555587749c4 in fifo8_push_all (fifo=fifo@entry=0x61f000005200, data=data@entry=0x7fff72bfa640 "", num=num@entry=0x24) at ../util/fifo8.c:43
#5  0x00005555572bd13e in esp_do_dma (s=s@entry=0x61f000005088) at ../hw/scsi/esp.c:577
#6  0x00005555572bfc8f in handle_ti (s=0x61f000005088) at ../hw/scsi/esp.c:845
#7  0x00005555572c419c in esp_reg_write (s=0x61f000005088, saddr=saddr@entry=0x3, val=<optimized out>)
    at ../hw/scsi/esp.c:987
#8  0x0000555557bb916a in esp_pci_io_write (opaque=0x61f000004680, addr=<optimized out>, val=<optimized out>, size=<optimized out>) at ../hw/scsi/esp-pci.c:214
#9  0x000055555817ea28 in memory_region_write_accessor (mr=0x61f000004f70, addr=<optimized out>, value=<optimized out>, size=<optimized out>, shift=<optimized out>, mask=<optimized out>, attrs=...) at ../softmmu/memory.c:491
#10 0x0000555558176671 in access_with_adjusted_size (addr=addr@entry=0xc, value=value@entry=0x7fff72bfb2a8, size=size@entry=0x1, access_size_min=<optimized out>, access_size_max=<optimized out>, access_fn=
    0x55555817e7c0 <memory_region_write_accessor>, mr=0x61f000004f70, attrs=...) at ../softmmu/memory.c:552
#11 0x00005555581892aa in memory_region_dispatch_write (mr=mr@entry=0x61f000004f70, addr=<optimized out>, data=<optimized out>, data@entry=0xffffff90, op=op@entry=MO_8, attrs=..., attrs@entry=...) at ../softmmu/memory.c:1508
#12 0x0000555558024b66 in address_space_stb (as=<optimized out>, addr=<optimized out>, val=<optimized out>, attrs=..., result=0x0) at /home/cwmyung/prj/hyfuzz/src/qemu-master/memory_ldst.c.inc:382
#13 0x00007fff9323641c in code_gen_buffer ()
#14 0x0000555557e793bb in cpu_tb_exec (tb_exit=<optimized out>, itb=<optimized out>, cpu=0x62e0000004b4)
    at ../accel/tcg/cpu-exec.c:190
#15 0x0000555557e793bb in cpu_loop_exec_tb (tb_exit=<optimized out>, last_tb=<optimized out>, tb=<optimized out>, cpu=0x62e0000004b4) at ../accel/tcg/cpu-exec.c:673
#16 0x0000555557e793bb in cpu_exec (cpu=cpu@entry=0x62e000000400) at ../accel/tcg/cpu-exec.c:798
#17 0x0000555557f5fc5a in tcg_cpus_exec (cpu=cpu@entry=0x62e000000400) at ../accel/tcg/tcg-accel-ops.c:68
#18 0x00005555582260af in mttcg_cpu_thread_fn (arg=arg@entry=0x62e000000400) at ../accel/tcg/tcg-accel-ops-mttcg.c:70
#19 0x0000555558777b05 in qemu_thread_start (args=<optimized out>) at ../util/qemu-thread-posix.c:521
#20 0x00007ffff05d26db in start_thread (arg=0x7fff72bff700) at pthread_create.c:463
#21 0x00007ffff02fb71f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
```


To reproduce the assertion failure, please run the QEMU with the following command line.

```

$ ./qemu-system-i386 -m 512 -drive file=./hyfuzz.img,index=0,media=disk,format=raw -device am53c974,id=scsi -device scsi-hd,drive=SysDisk -drive id=SysDisk,if=none,file=./disk.img

```

Please let me know if I can provide any further info.

Thank you.

- Cheolwoo, Myung (Seoul National University)



Thanks for the test case - looks like the problem occurs because a command hasn't been submitted before initiating a DMA transfer, and TC is set to a value higher than the size of cmdfifo. Can you confirm that the following fix works for you?

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 507ab363bc..0a26ee1dfd 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -573,6 +573,7 @@ static void esp_do_dma(ESPState *s)
         cmdlen = fifo8_num_used(&s->cmdfifo);
         trace_esp_do_dma(cmdlen, len);
         if (s->dma_memory_read) {
+            len = MIN(len, fifo8_num_free(&s->cmdfifo));
             s->dma_memory_read(s->dma_opaque, buf, len);
             fifo8_push_all(&s->cmdfifo, buf, len);
         } else {


ATB,

Mark.

QTest Reproducer:
/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, \
 * -m 512M -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001004
 * outw 0xcfc 0x01
 * outl 0xcf8 0x8000100e
 * outl 0xcfc 0x0e000000
 * outl 0xe40 0x03
 * outl 0xe0b 0x4100
 * outl 0xe0b 0x9000
 * EOF
 */
static void test_fuzz(void)
{
    QTestState *s = qtest_init(
        "-display none , -m 512M -device am53c974,id=scsi -device "
        "scsi-hd,drive=disk0 -drive "
        "id=disk0,if=none,file=null-co://,format=raw -nodefaults");
    qtest_outl(s, 0xcf8, 0x80001004);
    qtest_outw(s, 0xcfc, 0x01);
    qtest_outl(s, 0xcf8, 0x8000100e);
    qtest_outl(s, 0xcfc, 0x0e000000);
    qtest_outl(s, 0xe40, 0x03);
    qtest_outl(s, 0xe0b, 0x4100);
    qtest_outl(s, 0xe0b, 0x9000);
    qtest_quit(s);
}
int main(int argc, char **argv)
{
    const char *arch = qtest_get_arch();

    g_test_init(&argc, &argv, NULL);

    if (strcmp(arch, "i386") == 0) {
        qtest_add_func("fuzz/test_fuzz", test_fuzz);
    }

    return g_test_run();
}


Hello Mark,

I tested on fixed version, and checked that it does not trigger the assertion failure.

Thanks,
- Cheolwoo Myung

Thank you both for the reproducers. Please see the proposed patchset here:

https://lists.gnu.org/archive/html/qemu-devel/2021-03/msg06063.html


This is fixed now, thank you Mark.

Patchset v4:
https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg01000.html

Upstream commits:
https://git.qemu.org/?p=qemu.git;a=commit;h=0db895361b8a82e1114372ff9f48
https://git.qemu.org/?p=qemu.git;a=commit;h=e392255766071c8cac480da3a9ae
https://git.qemu.org/?p=qemu.git;a=commit;h=e5455b8c1c6170c788f3c0fd577c
https://git.qemu.org/?p=qemu.git;a=commit;h=c5fef9112b15c4b5494791cdf8bb
https://git.qemu.org/?p=qemu.git;a=commit;h=7b320a8e67a534925048cbabfa51
https://git.qemu.org/?p=qemu.git;a=commit;h=99545751734035b76bd372c4e721
https://git.qemu.org/?p=qemu.git;a=commit;h=fa7505c154d4d00ad89a747be2ed
https://git.qemu.org/?p=qemu.git;a=commit;h=fbc6510e3379fa8f8370bf71198f
https://git.qemu.org/?p=qemu.git;a=commit;h=0ebb5fd80589835153a0c2baa1b8
https://git.qemu.org/?p=qemu.git;a=commit;h=324c8809897c8c53ad05c3a7147d
https://git.qemu.org/?p=qemu.git;a=commit;h=607206948cacda4a80be5b976dba

I'm not able to change the status of this bug anymore. It should have been closed as "Fix committed" - QEMU 6.0.0 is not yet released.