USB assert failure on dev-storage.c

Bug #1523811 reported by Hajin Jang
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Fix Released
Undecided
Unassigned

Bug Description

On executing the attached python script in the guest OS, QEMU dies with assert failure:

[run python script in guest root shell]
# python a.py

[host message]
qemu-system-x86_64: hw/usb/dev-storage.c:445: usb_msd_handle_data: Assertion `le32_to_cpu(s->csw.residue) == 0' failed.
Aborted (core dumped)

When I detach the kernel driver and send CBW and reattach it again, without conforming to the command/data/status protocol, QEMU dies.
I think this is due to misimplementation of Command/Data/Status protocol in Bulk-only transfer.
This kind of assert failure can be misused by malwares to avoid being analyzed by terminating only in the virtual environments and still execute the malicious code in real machines.
Before running python script, make sure to change a.py that it should points to usb mass storage's vid and pid.

QEMU was running on these environment :
[CPU model] Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
[qemu version] QEMU 2.5.0-rc2 (compiled from source, gcc 4.8.4)
[host info] Ubuntu 14.04.3, x86_64, 3.19.0-32-generic
[guest info] Ubuntu 14.04.3, x86_64, 3.19.0-28-generic
[QEMU argument]
x86_64-softmmu/qemu-system-x86_64 -hda /media/hdd/img/ubuntu1404.qcow2.5 \
 -m 512 \
 --usbdevice disk:format=qcow2:../usb.img.5 \
 --enable-kvm

Tags: usb assert fuzzer
Revision history for this message
Hajin Jang (joveler) wrote :
Revision history for this message
Thomas Huth (th-huth) wrote :

Triaging old bug tickets ... can you still reproduce this issue with the latest version of QEMU (version 2.8)?

information type: Private Security → Public Security
Thomas Huth (th-huth)
Changed in qemu:
status: New → Incomplete
Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for QEMU because there has been no activity for 60 days.]

Changed in qemu:
status: Incomplete → Expired
Revision history for this message
Cheolwoo,Myung (cwmyung) wrote :
Download full text (6.1 KiB)

Using hypervisor fuzzer, hyfuzz, I found an assertion failure through nec-usb-xhci 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, 51db2d7cf26d05a961ec0ee0eb773594b32cc4a1)

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 -drive if=none,id=stick,file=./usbdisk.img,format=raw -device nec-usb-xhci,id=usb -device usb-storage,bus=usb.0,drive=stick

```

```

qemu-system-i386: ../hw/usb/dev-storage.c:454: void usb_msd_handle_data(USBDevice *, USBPacket *): Assertion `le32_to_cpu(s->csw.residue) == 0' failed.

#0 0x00007ffff1a60fb7 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff1a62921 in __GI_abort () at abort.c:79
#2 0x00007ffff1a5248a in __assert_fail_base (fmt=0x7ffff1bd9750 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x555557518dc0 <.str.30> "le32_to_cpu(s->csw.residue) == 0", file=file@entry=0x5555575189e0 <.str.19> "../hw/usb/dev-storage.c", line=line@entry=0x1c6, function=function@entry=0x555557518e20 <__PRETTY_FUNCTION__.usb_msd_handle_data> "void usb_msd_handle_data(USBDevice *, USBPacket *)") at assert.c:92
#3 0x00007ffff1a52502 in __GI___assert_fail (assertion=0x555557518dc0 <.str.30> "le32_to_cpu(s->csw.residue) == 0", file=0x5555575189e0 <.str.19> "../hw/usb/dev-storage.c", line=0x1c6, function=0x555557518e20 <__PRETTY_FUNCTION__.usb_msd_handle_data> "void usb_msd_handle_data(USBDevice *, USBPacket *)") at assert.c:101
#4 0x0000555556299749 in usb_msd_handle_data (dev=<optimized out>, p=<optimized out>) at ../hw/usb/dev-storage.c:454
#5 0x00005555563120b3 in usb_device_handle_data (dev=0x62300000a900, p=0x611001da3fc8) at ../hw/usb/bus.c:180
#6 0x000055555610ac07 in usb_process_one (p=0x611001da3fc8) at ../hw/usb/core.c:406
#7 0x0000555556109d8f in usb_handle_packet (dev=0x62300000a900, p=<optimized out>) at ../hw/usb/core.c:438
#8 0x000055555687de55 in xhci_submit (xhci=<optimized out>, xfer=<optimized out>, epctx=<optimized out>) at ../hw/usb/hcd-xhci.c:1779
#9 0x000055555687de55 in xhci_fire_transfer (xhci=<optimized out>, xfer=<optimized out>, epctx=<optimized out>) at ../hw/usb/hcd-xhci.c:1788
#10 0x000055555687de55 in xhci_kick_epctx (epctx=<optimized out>, streamid=0x0) at ../hw/usb/hcd-xhci.c:1947
#11 0x000055555688c7f6 in xhci_kick_ep (xhci=<optimized out>, slotid=<optimized out>, epid=<optimized out>, streamid=0x0) at ../hw/usb/hcd-xhci.c:1813
#12 0x00005555568943b7 in xhci_doorbell_write (ptr=<optimized out>, reg=0x1, val=0x4, size=<optimized out>) at ../hw/usb/hcd-xhci.c:3114
#13 0x0000555556c6617a in memory_region_write_accessor (mr=<optimized out>, addr=<optimized out>, value=<optimized out>, size=<optimized out>, shift=<optimized out>, mask=<optimized out>, attrs=...) at ../softmmu/memory.c:491
#14 0x0000555556c65d96 in access_with_adjusted_size (addr=<optimized out>, value=<optimized out>, size=<optimized out>, access_size_min=<optimized out>, access_size_max=<optimized out>, access_fn=<...

Read more...

Peter Maydell (pmaydell)
tags: added: fuzzer
Cheolwoo,Myung (cwmyung)
description: updated
Revision history for this message
Philippe Mathieu-Daudé (philmd) wrote :

Looking at commit 0659879e6e5 ("usb-storage: remove MSDState->residue")
this assert seems a left-over, CSW residue should be irrelevant in CBW
path...
Gerd, can we simply remove it?

Changed in qemu:
status: Expired → Confirmed
Revision history for this message
Gerd Hoffmann (kraxel-redhat) wrote :

No, we can't. csw.residue is non-zero if the request didn't complete yet (usb_msd_send_status clears it via memset). We *really* should not be in USB_MSDM_CBW state with a non-zero residue.
We need to figure how we end up with this inconsistency. Possibly via usb_msd_handle_reset().

Revision history for this message
Thomas Huth (th-huth) wrote :
Changed in qemu:
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Bug attachments