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
|
qemu-system-i386: void msix_vector_use(PCIDevice *, unsigned int): Assertion `vector < dev->msix_entries_nr' failed.
Description of problem:
While fuzzing, we observed a assertion failures in several virtio devices supporting msi-x functionality.
Steps to reproduce:
Here is qtest reproducer:
```bash
cat << EOF | qemu-system-i386 -display none -machine accel=qtest, -m 512M -machine pc -nodefaults \
-device virtio-mouse-pci,vectors=19923041 -qtest stdio
outl 0xcf8 0x80001020
outl 0xcfc 0xe0800000
outl 0xcf8 0x80001004
outw 0xcfc 0x02
write 0xe0800010 0x4 0x6100
EOF
```
and execution log:
```
cat << EOF | qemu-system-i386 -display none -machine accel=qtest, -m 512M -machine pc -nodefaults \
-device virtio-mouse-pci,vectors=19923041 -qtest stdio
outl 0xcf8 0x80001020
outl 0xcfc 0xe0800000
outl 0xcf8 0x80001004
outw 0xcfc 0x02
write 0xe0800010 0x4 0x6100
EOF
[I 0.000001] OPENED
[R +0.067760] outl 0xcf8 0x80001020
[S +0.067795] OK
OK
[R +0.067821] outl 0xcfc 0xe0800000
[S +0.067959] OK
OK
[R +0.067993] outl 0xcf8 0x80001004
[S +0.068005] OK
OK
[R +0.068020] outw 0xcfc 0x02
[S +0.068520] OK
OK
[R +0.068554] write 0xe0800010 0x4 0x6100
qemu-system-i386: ../hw/pci/msix.c:569: void msix_vector_use(PCIDevice *, unsigned int): Assertion `vector < dev->msix_entries_nr' failed.
Aborted
```
If you need more information, let me know so I can discuss more about this issue.
Additional information:
```c
int msix_init(PCIDevice *dev, unsigned short nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos,
Error **errp);
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
uint8_t bar_nr, Error **errp);
```
`msix_init` accepts `nentries` as `unsigned short` type.
```c
static void virtio_pci_device_plugged(DeviceState *d, Error **errp):
...
if (proxy->nvectors) {
int err = msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors,
proxy->msix_bar_idx, NULL);
if (err) {
/* Notice when a system that supports MSIx can't initialize it */
if (err != -ENOTSUP) {
warn_report("unable to init msix vectors to %" PRIu32,
proxy->nvectors);
}
proxy->nvectors = 0;
}
}
```
When virtio-pci device is initialized, `proxy->nvectors` (`uint32_t` here) is casted into `unsigned short`.
This causes inconsistency between `msix_entries_nr` and `nvectors` and triggers the above crash.
While this is due to setting invalid value to `nvectors`, we need proper handling of the wrong value in the configuration.
|