mirror of https://github.com/xemu-project/xemu.git
![]() An abort happens in ohci_frame_boundary() when ohci->done is 0 [1].
``` c
static void ohci_frame_boundary(void *opaque)
{
// ...
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
if (!ohci->done)
abort(); <----------------------------------------- [1]
```
This was reported in https://bugs.launchpad.net/qemu/+bug/1911216/,
https://lists.gnu.org/archive/html/qemu-devel/2021-06/msg03613.html, and
https://gitlab.com/qemu-project/qemu/-/issues/545. I can still reproduce it with
the latest QEMU.
This happends due to crafted ED with putting ISO_TD at physical address 0.
Suppose ed->head & OHCI_DPTR_MASK is 0 [2], and we memset 0 to the phyiscal
memory from 0 to sizeof(ohci_iso_td). Then, starting_frame [3] and frame_count
[4] are both 0. As we can control the value of ohci->frame_number (0 to 0x1f,
suppose 1), we then control the value of relative_frame_number to be 1 [6]. The
control flow goes to [7] where ohci->done is 0. Have returned from
ohci_service_iso_td(), ohci_frame_boundary() will abort() [1].
``` c
static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
{
// ...
addr = ed->head & OHCI_DPTR_MASK; // <--------------------- [2]
if (ohci_read_iso_td(ohci, addr, &iso_td)) { // <-------- [3]
// ...
starting_frame = OHCI_BM(iso_td.flags, TD_SF); // <-------- [4]
frame_count = OHCI_BM(iso_td.flags, TD_FC); // <-------- [5]
relative_frame_number = USUB(ohci->frame_number, starting_frame);
// <-------- [6]
if (relative_frame_number < 0) {
return 1;
} else if (relative_frame_number > frame_count) {
// ...
ohci->done = addr; // <-------- [7]
// ...
}
```
As only (afaik) a guest root user can manipulate ED, TD and the physical memory,
this assertion failure is not a security bug.
The idea to fix this issue is to drop ohci_service_iso_td() if ed->head &
OHCI_DPTR_MASK is 0, which is similar to the drop operation for
ohci_service_ed_list() when head is 0. Probably, a similar issue is in
ohci_service_td(). I drop ohci_service_td() if ed->head & OHCI_DPTR_MASK is 0.
Fixes:
|
||
---|---|---|
.. | ||
Kconfig | ||
bus.c | ||
canokey.c | ||
canokey.h | ||
ccid-card-emulated.c | ||
ccid-card-passthru.c | ||
ccid.h | ||
chipidea.c | ||
combined-packet.c | ||
core.c | ||
desc-msos.c | ||
desc.c | ||
desc.h | ||
dev-audio.c | ||
dev-hid.c | ||
dev-hub.c | ||
dev-mtp.c | ||
dev-network.c | ||
dev-serial.c | ||
dev-smartcard-reader.c | ||
dev-storage-bot.c | ||
dev-storage-classic.c | ||
dev-storage.c | ||
dev-uas.c | ||
dev-wacom.c | ||
hcd-dwc2.c | ||
hcd-dwc2.h | ||
hcd-dwc3.c | ||
hcd-ehci-pci.c | ||
hcd-ehci-sysbus.c | ||
hcd-ehci.c | ||
hcd-ehci.h | ||
hcd-musb.c | ||
hcd-ohci-pci.c | ||
hcd-ohci.c | ||
hcd-ohci.h | ||
hcd-uhci.c | ||
hcd-uhci.h | ||
hcd-xhci-nec.c | ||
hcd-xhci-pci.c | ||
hcd-xhci-pci.h | ||
hcd-xhci-sysbus.c | ||
hcd-xhci-sysbus.h | ||
hcd-xhci.c | ||
hcd-xhci.h | ||
host-libusb.c | ||
host.h | ||
imx-usb-phy.c | ||
libhw.c | ||
meson.build | ||
pcap.c | ||
quirks-ftdi-ids.h | ||
quirks-pl2303-ids.h | ||
quirks.c | ||
quirks.h | ||
redirect.c | ||
trace-events | ||
trace.h | ||
tusb6010.c | ||
u2f-emulated.c | ||
u2f-passthru.c | ||
u2f.c | ||
u2f.h | ||
vt82c686-uhci-pci.c | ||
xen-usb.c | ||
xlnx-usb-subsystem.c | ||
xlnx-versal-usb2-ctrl-regs.c |