External USB fuzzing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg and Alan!

As you might know I've been working on adding external USB fuzzing
support to syzkaller.

At this point a have a prototype, which is able to emulate USB devices
from userspace via a custom written userspace interface for the gadget
subsystem and CONFIG_USB_DUMMY_HCD. The patches and some details are
here [1].

This is just a prototype and there are a few things we need to support
USB fuzzing properly.

1. A way to collect coverage from USB code.

Syzkaller uses kcov (CONFIG_KCOV) to collect coverage from the kernel.
The issue is that kcov collects coverage in a process context (from
the kernel task that corresponds to the userspace process that created
the kcov device). But AFAIU USB uses a kernel worker to process USB
hub events.

The approach I tried to deal with this is to change hub_event() to put
events into a global queue and wait instead of processing them right
away. Then I added an ioctl to the hub device that takes an event from
the queue and processes it the same way hub_event() used to. This
results in USB events being processed in a process context. The patch
is here [2].

Is there a less hacky way to make processing USB events synchronously
(by an ioctl call from userspace for example), if that's feasible at
all?

The perfect solution would be to have something like /dev/tun for USB,
where you can write USB packets and the kernel would synchronously
process them. I'm not sure whether this is possible (highly
asynchronous USB core subsystem architecture + all communication is
initiated by the host).

Another thing we could do is to teach kcov to collect coverage from
arbitrary kernel threads. In this case we could collect coverage from
the thread that processes the USB events. However we would still need
some signal to understand whether the device finished initialization,
etc. (with the first approach we could tell that some stage of device
initialization is finished by seeing that hub_event() returned).

There's another issue with getting coverage after USB device has been
initialized. For example some device drivers create new threads that
communicate with that device. I don't see an easy way to collect
coverage from those threads.

2. A way to isolate independent test programs.

Right now CONFIG_USB_DUMMY_HCD creates one global hub to which all
emulated USB devices connect. Would it be possible to create one
virtual hub per test (or at least one per test process) by say calling
some ioctl? What changes would that require?

Basically we need a way to run a test program (that connects a USB
device and works with it from userspace for example) and then destroy
all the accumulated state before running the next test.

Thanks!

[1] https://github.com/google/syzkaller/blob/usb-fuzzer/docs/linux/external_fuzzing_usb.md

[2] https://github.com/google/syzkaller/blob/usb-fuzzer/tools/usb/0001-usb-fuzzer-add-hub-hijacking-ioctl.patch
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux