diff options
| author | Andrey Konovalov <andreyknvl@google.com> | 2019-07-22 19:25:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-22 19:25:54 +0200 |
| commit | 55e0c07757deebc0c6094915fae19fc0959849e4 (patch) | |
| tree | aef999dbc037a017cdb142fca9911223d0bd1c3f /sys/linux/init_vusb.go | |
| parent | 6a786da97c822c3ad536290c412f472e58342c91 (diff) | |
sys/linux: extract USB HID ids (#1294)
* sys/linux: extract USB HID ids
As it turns out the HID kernel subsystem registers only one USB driver that
checks that the interface of the connected device has HID class and then looks
up its own list of vendor/device ids to find a matching driver. This means
that we currently don't generate proper vendor/device ids for USB HID devices.
This patch updates the syz-usbgen tool to also extract USB HID vendor/device
ids from a running kernel and makes the generated descriptions for HID devices
to be patched using the extracted ids.
This patch also contains some minor improvements to USB descriptions
(better HID descriptions and more replies for some USB classes/drivers).
* sys/linux: run make generate
Diffstat (limited to 'sys/linux/init_vusb.go')
| -rw-r--r-- | sys/linux/init_vusb.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/linux/init_vusb.go b/sys/linux/init_vusb.go index d388914a7..ac7024182 100644 --- a/sys/linux/init_vusb.go +++ b/sys/linux/init_vusb.go @@ -25,6 +25,7 @@ const ( USB_DEVICE_ID_MATCH_INT_NUMBER BytesPerUsbID = 17 + BytesPerHidID = 12 ) type UsbDeviceID struct { @@ -42,6 +43,13 @@ type UsbDeviceID struct { BInterfaceNumber uint8 } +type HidDeviceID struct { + Bus uint16 + Group uint16 + Vendor uint32 + Product uint32 +} + func (arch *arch) generateUsbDeviceDescriptor(g *prog.Gen, typ0 prog.Type, old prog.Arg) ( arg prog.Arg, calls []*prog.Call) { @@ -119,6 +127,36 @@ func (arch *arch) generateUsbDeviceDescriptor(g *prog.Gen, typ0 prog.Type, old p return } +func (arch *arch) generateUsbHidDeviceDescriptor(g *prog.Gen, typ0 prog.Type, old prog.Arg) ( + arg prog.Arg, calls []*prog.Call) { + + if old == nil { + arg = g.GenerateSpecialArg(typ0, &calls) + } else { + arg = old + calls = g.MutateArg(arg) + } + if g.Target().ArgContainsAny(arg) { + return + } + + totalIds := len(hidIds) / BytesPerHidID + idNum := g.Rand().Intn(totalIds) + base := hidIds[idNum*BytesPerHidID : (idNum+1)*BytesPerHidID] + + p := strings.NewReader(base) + var id HidDeviceID + if binary.Read(p, binary.LittleEndian, &id) != nil { + panic("not enough data to read") + } + + devArg := arg.(*prog.GroupArg).Inner[0] + patchGroupArg(devArg, 7, "idVendor", uint64(id.Vendor)) + patchGroupArg(devArg, 8, "idProduct", uint64(id.Product)) + + return +} + func patchGroupArg(arg prog.Arg, index int, field string, value uint64) { fieldArg := arg.(*prog.GroupArg).Inner[index].(*prog.ConstArg) if fieldArg.Type().FieldName() != field { |
