Bug 83551 - Kernel OOPses on access to address 0x8 when cdc-acm device is inserted with invalid descriptor.
Summary: Kernel OOPses on access to address 0x8 when cdc-acm device is inserted with i...
Status: NEW
Alias: None
Product: Drivers
Classification: Unclassified
Component: USB (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Greg Kroah-Hartman
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-31 10:15 UTC by Simon Schubert
Modified: 2014-08-31 15:54 UTC (History)
0 users

See Also:
Kernel Version: 3.16 (tested), v3.17-rc2-227-gfd5984d (visually)
Subsystem:
Regression: No
Bisected commit-id:


Attachments
Move interface validity check to cover both branches (684 bytes, patch)
2014-08-31 10:15 UTC, Simon Schubert
Details | Diff

Description Simon Schubert 2014-08-31 10:15:37 UTC
Created attachment 148871 [details]
Move interface validity check to cover both branches

*** Setting
Invalid configuration descriptor as follows:

#+BEGIN_SRC text
0000   09 02 43 00 02 01 00 80 64 09 04 00 00 01 02 02  ..C.....d.......
0010   00 00 05 24 00 10 01 04 24 02 06 04 24 01 00 01  ...$....$...$...
0020   05 24 06 00 01 07 05 81 03 08 00 ff 09 04 01 00  .$..............
0030   02 0a 00 00 00 07 05 82 02 40 00 ff 07 05 01 02  .........@......
0040   20 00 ff                                          ..
#+END_SRC text

In particular, the CDC Call Management Descriptor has its length
declared too short (4 instead of 5), and the following CDC Union
Descriptor is therefore unreachable.

*** Code problems
Multiple issues:

1. The ~while (buflen > 0)~ loop that parses the interface aux data
   does not perform correct boundary checking.  In the above case,
   ~call_interface_num = buffer[4];~ accesses outside of the
   (declared) descriptor content.
2. If a union header is missing, there is no code path that checks
   whether the ~data_interface~ (resolved from ~call_interface_num~)
   actually exists.  Later ~if
   (data_interface->cur_altsetting->desc.bInterfaceClass~ dereferences
   ~data_interface~.

*** Proposed solution
Move the ~if (!control_interface || !data_interface)~ block out the
~if (!union_header)~ conditional.  That way both branches will benefit
from the check.  This only addresses issue (2), not issue (1).  See attachment.
Comment 1 Greg Kroah-Hartman 2014-08-31 15:54:44 UTC
On Sun, Aug 31, 2014 at 10:15:37AM +0000, bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=83551
> 
>             Bug ID: 83551
>            Summary: Kernel OOPses on access to address 0x8 when cdc-acm
>                     device is inserted with invalid descriptor.

Can you please send this to the linux-usb@vger.kernel.org mailing list?

Note You need to log in before you can comment on or make changes to this bug.