From 55e0c07757deebc0c6094915fae19fc0959849e4 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Mon, 22 Jul 2019 19:25:54 +0200 Subject: 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 --- sys/linux/init_vusb.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'sys/linux/init_vusb.go') 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 { -- cgit mrf-deployment