Closed Bug 1219814 Opened 9 years ago Closed 9 years ago

Overflow in RtpHeaderParser::Parse can cause memory-safety bug

Categories

(Core :: WebRTC: Audio/Video, defect, P1)

41 Branch
defect

Tracking

()

RESOLVED FIXED
Tracking Status
firefox43 --- fixed
firefox44 --- fixed
firefox45 --- fixed
firefox-esr38 43+ fixed

People

(Reporter: q1, Assigned: jesup)

References

Details

(Keywords: csectype-bounds, sec-high)

RtpHeaderParser::Parse (media\webrtc\trunk\webrtc\modules\rtp_rtcp\source\rtp_utility.cc) can overflow while parsing the packet extension:

378:  if (X) {
379:    /* RTP header extension, RFC 3550.
370:     0                   1                   2                   3
381:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
382:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
383:    |      defined by profile       |           length              |
384:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
385:    |                        header extension                       |
386:    |                             ....                              |
387:    */
388:    const ptrdiff_t remain = _ptrRTPDataEnd - ptr;
389:    if (remain < 4) {
390:      return false;
391:    }
392:
393:    header.headerLength += 4;
394:
395:    uint16_t definedByProfile = *ptr++ << 8;
396:    definedByProfile += *ptr++;
397:
398:    uint16_t XLen = *ptr++ << 8;
399:    XLen += *ptr++; // in 32 bit words
400:    XLen *= 4; // in octs
401:
402:    if (remain < (4 + XLen)) {
403:      return false;
404:    }
405:    if (definedByProfile == kRtpOneByteHeaderExtensionId) {
406:      const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen;
407:      ParseOneByteExtensionHeader(header,
408:                                  ptrExtensionMap,
409:                                  ptrRTPDataExtensionEnd,
410:                                  ptr);
411:    }
412:    header.headerLength += XLen;
413:  }
414:  return true;
415:}

This can occur if the 2 length bytes fetched in lines 398-99 total >= 0x4000. Choosing exactly 0x4000, line 400 then computes 0. This passes the test on line 402, has no impact on lines 405-11, |leaves header.headerLength| on line 412 unchanged, and causes success status to be returned.

Later, other code (such as srtp_unprotect; see https://bugzilla.mozilla.org/show_bug.cgi?id=1216837 and especially https://bugzilla.mozilla.org/show_bug.cgi?id=1216837#c3) can fetch the same length bytes from the packet and use them without further validation, since RtpHeaderParser::Parse supposedly validated them, causing potential reads and writes beyond the packet bounds.
Flags: sec-bounty?
Group: core-security → media-core-security
Assignee: nobody → rjesup
See bug 1220493, which has a patch to fix that and this together.
See Also: → CVE-2015-7205
backlog: --- → webrtc/webaudio+
Rank: 10
Priority: -- → P1
bounty decision waiting for an answer to bug 1220493 comment 17
Fixed in bug 1220493.  See my comment there.
Status: NEW → RESOLVED
Closed: 9 years ago
Flags: needinfo?(dveditz)
Resolution: --- → FIXED
Group: media-core-security → core-security-release
Flags: needinfo?(dveditz)
According to bug 1220493 comment 18 this bug was actually fixed upstream independently which is technically a dupe. The bounty committee has decided to award our smaller "moderate" bounty as a thank-you anyway.
Flags: sec-bounty? → sec-bounty+
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.