Bug 672789 (CVE-2011-2992)

this script reliably crashes Firefox 5 on Linux, Mac and Windows by streaming an ogg file through a proxy




7 years ago
4 years ago


(Reporter: ahu, Assigned: cpearce)


(5 keywords)

5 Branch
crash, reproducible, testcase, verified-aurora, verified-beta
Bug Flags:
sec-bounty +

Firefox Tracking Flags

(firefox5 wontfix, firefox6+ fixed, firefox7+ fixed, firefox8+ fixed, status1.9.2 unaffected)


(Whiteboard: [sg:critical?][qa!], crash signature)


(3 attachments)



7 years ago
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.124 Safari/534.30

Steps to reproduce:

Connect to a proxyserver & stream a specific ogg file to an HTML5 player. Then I seek to a part that has not yet been loaded. 

Actual results:

On firefox 4 this works, on 5 and 6 I get a crossplatform crash (Windows, Linux, Mac), a segfault

Expected results:

No segfault.
Please let us know the Crash ID for the crashes you submitted.
Severity: normal → critical

Comment 2

7 years ago
Also, please provide a link to the ogg video and/or script that causes the crash.


7 years ago
Crash Signature: bp-8a8b28c4-3cb3-4e1c-9a28-cddc02110720 bp-e409ab9b-bcd4-4eba-a0ec-d161f2110720

Comment 3

7 years ago
Created attachment 547095 [details]
a little proxy-server that feeds the video-file slowly

This is a tarball containing a little proxy-server that helped me to reproduce the error.

After starting the proxy-server, let firefox connect to port 8000.
Then browse to www.video.com

A webcam-video will be shown. The proxy-server will feed the data very slowly, which allows you to seek to the end of the video before it is fully loaded.
When you seek to a part that isn't fetched yet, a segfault will occur.

the proxy-server is replying to the request with HTTP/1.1 200 OK and not with 206 Partial content. No filesize will be transmitted. To report the duration of the video to firefox, the "X-Content-Duration:"-header is used. Maybe this is relevant for this issue.

Comment 4

7 years ago
Moving Report IDs from the Crash Signature field, and adding the signatures there instead.
Crash Signature: bp-8a8b28c4-3cb3-4e1c-9a28-cddc02110720 bp-e409ab9b-bcd4-4eba-a0ec-d161f2110720 → [@ nsCSSRendering::FindBackgroundStyleFrame ] [@ js::PropertyTable::search ]
OS: Other → Linux
Hardware: All → x86_64


7 years ago
Group: core-security
Ever confirmed: true
Whiteboard: [sg:critical?]
I can reproduce this reliably in a local trunk debug build on Linux64.
Before the crash I see this on the console:

###!!! ASSERTION: Guess must be before range end: 'guess < endOffset', file content/media/ogg/nsOggReader.cpp, line 1252
WARNING: NS_ENSURE_TRUE(ret == 0) failed: file content/media/ogg/nsOggReader.cpp, line 1127
WARNING: NS_ENSURE_TRUE(res != PAGE_SYNC_ERROR) failed: file content/media/ogg/nsOggReader.cpp, line 1268
WARNING: NS_ENSURE_SUCCESS(res, res) failed with result 0x80004005: file content/media/ogg/nsOggReader.cpp, line 1066

then I crash with a SEGV in random parts of the code.
Our video code is overwriting random pieces of memory?
Component: General → Video/Audio
Keywords: crash, reproducible, testcase
Product: Firefox → Core
QA Contact: general → video.audio

Comment 6

7 years ago
Bug 462960 should prevent this error by ensuring we never try to seek into ranges which are unbuffered in a resource/connection which doesn't support HTTP byte range requests.


7 years ago
tracking-firefox6: --- → ?
tracking-firefox7: --- → ?
tracking-firefox8: --- → ?


7 years ago
Depends on: 462960

Comment 7

7 years ago
Paul, it would be really great if we could get bug 462960 and its dependencies landed. The changes to the seek algorithm you make in bug 462960 should prevent this crash happening.
Bug 462960 changes an existing scriptable API (nsIDOMHTMLMediaElement).
Does our process allow that on mozilla-aurora and -beta ?

Comment 9

7 years ago
Not sure.

If we can't get bug 462960 on m-a or m-b, we could probably do a simple fix in each of the Ogg/Wave/WebM backend's to not seek into unbuffered ranges if the media isn't reporting that it supports byte range requests.

Comment 10

7 years ago
Created attachment 547320 [details] [diff] [review]
Patch: minimal fix

I suspect that since the patch from bug 462960 changes guids on interfaces wouldn't be wanted on m-{a,b} because it may affect binary add-ons?

Here's a patch to implement the minimal fix, pretty much what I described in comment 9. With this if you try to seek into an unbuffered range, the seek just aborts and playback continues from the previous playback position.
Assignee: nobody → chris
Attachment #547320 - Flags: review?(kinetik)
Comment on attachment 547320 [details] [diff] [review]
Patch: minimal fix

Review of attachment 547320 [details] [diff] [review]:

::: content/media/nsBuiltinDecoderReader.cpp
@@ +44,5 @@
>  #include "nsBuiltinDecoderReader.h"
>  #include "nsBuiltinDecoderStateMachine.h"
>  #include "mozilla/mozalloc.h"
>  #include "VideoUtils.h"
> +#include "nsTimeRanges.h"

This can be included in the .cpp file.

::: content/media/nsBuiltinDecoderStateMachine.h
@@ +417,5 @@
>    void DecodeSeek();
> +  // Returns PR_TRUE if mSeekTarget is not in a buffered range and we
> +  // cannot seek the media into unbuffered ranges.
> +  PRBool IsSeekTargetUnreachable();

Would you mind renaming this to IsSeekTargetReachable and inverting the result and the test where we use it?
Attachment #547320 - Flags: review?(kinetik) → review+
How is this potentially exploitable? It appears we'd read "ogg data" from uninitialized or unowned memory. If it doesn't crash on an access violation (safe) how is that different than someone feeding us a garbage ogg stream (which shouldn't be exploitable or else we've got worse problems!).

The two crash stacks attached to this bug are both null derefs.
I think we should take this minimal fix for branches.
status-firefox5: --- → wontfix
status-firefox6: --- → affected
status-firefox7: --- → affected
status-firefox8: --- → affected
tracking-firefox5: --- → -
tracking-firefox6: ? → +
tracking-firefox7: ? → +
tracking-firefox8: ? → +
Created attachment 547540 [details]
more stacks

(In reply to comment #12)
>It appears we'd read "ogg data" from uninitialized or unowned memory.

That's not what I'm seeing using a local debug build on Linux64.
I'm not crashing in the ogg decoder, but some time later in arbitrary
parts of the code.  I looked at more than a dozen crashes and all of
them appeared to have been caused by arbitrary memory being overwritten.
I'm assuming that the bug in the ogg code caused this to happen and I'm
worried that what was written can be influenced by the stream.

Here's a few of the crash stacks.
(JaegerTrampoline() sounds like a bad place to crash...)

Comment 15

7 years ago
(In reply to comment #12)
> How is this potentially exploitable?

In this case we're reading data from file and writing it to memory. Due to unsigned integer overflow, in this case we'll end up writing however much we've downloaded from file into our 8KB memory buffer. Chances are we'll have downloaded more than 8KB by this stage, and we'll end up overflowing the bounds of that buffer and stomping memory with whatever was read from file.

This is caused by unsigned values overflowing at nsOggReader.cpp:1100 (aEndOffset==-1 as the stream's length is unknown). Matthew Gregan picked this up in bug 652721. With his patch applied, when we seek in this case, rather than crashing the media is just rendered unplayable (due the playback engine not recovering from a failed seek correctly, it's not an artefact of his patch).

Ideally we should take Matthew's patch in bug 652721 on central + branches to fix the crash, and then take Paul's patches in bug 462960 on central to prevent us trying to seek into unbuffered ranges when the stream isn't seekable. Paul's patches make my patch in this bug unnecessary, so we may as well take his patches instead.

Comment 16

7 years ago
Fixed on central, aurora, and beta by landing of bug 652721.
Last Resolved: 7 years ago
status-firefox5: wontfix → ---
status-firefox6: affected → ---
status-firefox7: affected → ---
status-firefox8: affected → ---
tracking-firefox5: - → ---
tracking-firefox6: + → ?
tracking-firefox7: + → ?
tracking-firefox8: + → ?
Depends on: 652721
No longer depends on: 462960
OS: Linux → All
Hardware: x86_64 → All
Resolution: --- → FIXED

Comment 17

7 years ago
Sorry, the tracking flags got reset (maybe a bug in bugzilla helper?). I can't reset the tracking-firefoxN flags, but have reset the other ones.
status-firefox5: --- → wontfix
status-firefox6: --- → fixed
status-firefox7: --- → fixed
status-firefox8: --- → fixed
No worries, thanks for landing the fix!
tracking-firefox6: ? → +
tracking-firefox7: ? → +
tracking-firefox8: ? → +

Comment 19

7 years ago
Hi everybody,

On behalf of Theo and me, thank you very much for resolving this issue so quickly, we are much impressed!

Keep up the great work.

blocking1.9.2: --- → .20+
status1.9.2: --- → wanted
Is this crash a regression? I can't find the affected code on the 1.9.2 branch.
blocking1.9.2: .20+ → ?
status1.9.2: wanted → ?

Comment 22

7 years ago
Yes, this is a regression in 5.0. I was unable to reproduce the crash in [Mozilla/4.0 (Windows; U; Windows NT 6.1; en-US; rv: Gecko/20110319 Firefox/3.6.16].

Comment 23

7 years ago
(In reply to Chris Pearce [:cpearce] from comment #22)
> Yes, this is a regression in 5.0.

Sorry, I meant 4.0.
blocking1.9.2: ? → ---
status1.9.2: ? → .20-fixed
"unaffected" is a better status
status1.9.2: .20-fixed → unaffected
Alias: CVE-2011-2992
qa+ for verification in Firefox 7 and 8
Whiteboard: [sg:critical?] → [sg:critical?][qa+]
Verified this on Linux on 6.0.2, 7.0RC(build2), and 8.0a2 using the steps in comment #0 and comment #3. In Fx5 moving the seek handle beyond what it has loaded crashed the application. In the fixed versions it does not crash.
Keywords: verified-aurora, verified-beta
Verified fixed based on comment 26.
Whiteboard: [sg:critical?][qa+] → [sg:critical?][qa!]
Group: core-security
Flags: sec-bounty+
You need to log in before you can comment on or make changes to this bug.