summary refs log tree commit diff stats
path: root/gitlab/issues_text/target_i386/host_missing/accel_missing/2631
blob: cce15ebc7d52d610d4d94a0ba9e4cab6da2f157b (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
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.