[Pkg-oss4-maintainers] Bug#775662: oss4: Insufficient validation of USB device descriptors

Ben Hutchings ben at decadent.org.uk
Sun Jan 18 10:24:30 UTC 2015


Source: oss4
Version: 4.2-build2006-2
Severity: critical
Tags: security

[This was originally sent to the security team in 2012 but didn't go
further than that.  However, the code has not changed at all since
then.]

In kernel/drv/oss_usb/oss_usb.c:

- count_source_controls(), add_controls_for_mixer(),
  add_controls_for_proc(), add_controls_for_selector(),
  translate_feature_mask_usb2(), translate_feature_mask(),
  add_controls_for_feature(), traverse_source_controls(),
  traverse_target_controls(), setup_legacy_mixer(),
  get_feature_mask(), mixer_dump() and ossusb_init_audioctl()
  do not check that descriptors are as long as expected.
- setup_legacy_mixer() does not reject invalid source unit numbers.
  These are arbitrary unsigned bytes but used as an index within an
  array of length 40.

In kernel/drv/oss_usb/ossusb_audio.c:

- prepare_altsetting() does not reject altsetting descriptors with an
  invalid terminal link unit number.
- setup_format_I() and setup_format_II() do not check that descriptors
  are as long as expected.

In kernel/drv/oss_usb/ossusb_midi.c:

- ossusb_init_midistream() does not check that descriptors are as
  long as expected.  (It requires that an altsetting descriptor is
  at least 3 bytes long, but may use more than that.)

While unit numbers are validated in some places, validation is
inconsistent and probably wrong:

      if (un->source <= 0 && un->source < devc->nunits)
    if (*d > 0 && *d < devc->nunits)
  if (portc->terminal_link > 0 && portc->terminal_link <= devc->nunits)

An invalid USB device descriptor may cause memory corruption or a
crash.

I didn't find any case where the driver would copy a lot of data from
the device descriptor, but I know people manage to exploit bugs for
privilege escalation even though they provide only very limited control
over the data to be written.

[I just noticed another bug in count_source_controls():

  un = &devc->units[unit];
  d = un->desc;

  if (un == NULL)
    return 0;

It's a bit late to be checking for a null pointer here.  Thankfully this
shouldn't cause anything worse than a crash on Linux.]

Ben.

-- 
Ben Hutchings
The generation of random numbers is too important to be left to chance.
                                                            - Robert Coveyou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 811 bytes
Desc: This is a digitally signed message part
URL: <http://lists.alioth.debian.org/pipermail/pkg-oss4-maintainers/attachments/20150118/4e157fcb/attachment.sig>


More information about the Pkg-oss4-maintainers mailing list