Bug 1020205 (CVE-2014-1549)

heap-buffer-overflow in mozilla::dom::AudioBufferSourceNodeEngine::CopyFromInputBuffer

VERIFIED FIXED in Firefox 31

Status

()

--
critical
VERIFIED FIXED
5 years ago
3 years ago

People

(Reporter: attekett, Assigned: karlt)

Tracking

(5 keywords)

unspecified
mozilla33
x86_64
Linux
crash, csectype-bounds, regression, sec-high, testcase
Points:
---
Bug Flags:
sec-bounty +
in-testsuite +

Firefox Tracking Flags

(firefox29 wontfix, firefox30 wontfix, firefox31+ verified, firefox32+ verified, firefox33+ verified, firefox-esr24 unaffected, b2g-v1.3 fixed, b2g-v1.3T fixed, b2g-v1.4 fixed, b2g-v2.0 fixed, b2g-v2.1 fixed)

Details

(Whiteboard: [adv-main31+])

Attachments

(4 attachments)

(Reporter)

Description

5 years ago
Created attachment 8434019 [details]
Repro-file

Tested on:

OS: Ubuntu 12.04

Firefox: ASAN build from https://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-central-linux64-asan/1401807026/

ASAN-report:

==6994==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f37adc1aea0 at pc 0x43906e bp 0x7f37b1d150e0 sp 0x7f37b1d14898
READ of size 17179677220 at 0x7f37adc1aea0 thread T27 (MediaStreamGrph)
    #0 0x43906d in __interceptor_memcpy _asan_rtl_
    #1 0x7f37dc4b8e09 in mozilla::dom::AudioBufferSourceNodeEngine::CopyFromInputBuffer(mozilla::AudioChunk*, unsigned int, unsigned long, unsigned int) /home/attekett/firefox/content/media/webaudio/AudioBufferSourceNode.cpp:222
    #2 0x7f37dc4b830a in mozilla::dom::AudioBufferSourceNodeEngine::ProcessBlock(mozilla::AudioNodeStream*, mozilla::AudioChunk const&, mozilla::AudioChunk*, bool*) /home/attekett/firefox/content/media/webaudio/AudioBufferSourceNode.cpp:470
    #3 0x7f37dc3b0d10 in mozilla::AudioNodeStream::ProcessInput(long, long, unsigned int) /home/attekett/firefox/content/media/AudioNodeStream.cpp:468
    #4 0x7f37dc419781 in mozilla::MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(unsigned int, int, long, long) /home/attekett/firefox/content/media/MediaStreamGraph.cpp:1192
    #5 0x7f37dc41a83a in mozilla::MediaStreamGraphImpl::RunThread() /home/attekett/firefox/content/media/MediaStreamGraph.cpp:1356
    #6 0x7f37dc435fee in mozilla::(anonymous namespace)::MediaStreamGraphInitThreadRunnable::Run() /home/attekett/firefox/content/media/MediaStreamGraph.cpp:1512
    #7 0x7f37d8aade08 in nsThread::ProcessNextEvent(bool, bool*) /home/attekett/firefox/xpcom/threads/nsThread.cpp:766
    #8 0x7f37d8992e09 in NS_ProcessNextEvent(nsIThread*, bool) /home/attekett/firefox/xpcom/glue/nsThreadUtils.cpp:263
    #9 0x7f37d92b826c in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /home/attekett/firefox/ipc/glue/MessagePump.cpp:307
    #10 0x7f37d92461fe in MessageLoop::RunInternal() /home/attekett/firefox/ipc/chromium/src/base/message_loop.cc:229
    #11 0x7f37d8aab375 in nsThread::ThreadFunc(void*) /home/attekett/firefox/xpcom/threads/nsThread.cpp:346
    #12 0x7f37e4152e95 in _pt_root /home/attekett/firefox/nsprpub/pr/src/pthreads/ptthread.c:212
    #13 0x7f37e766ae99 in start_thread ??:0
    #14 0x7f37e67753fc in ?? ??:0

0x7f37adc1aea0 is located 0 bytes to the right of 149152-byte region [0x7f37adbf6800,0x7f37adc1aea0)
allocated by thread T0 here:
    #0 0x45f9d5 in __interceptor_calloc _asan_rtl_
    #1 0x7f37df8b439a in js_calloc(unsigned long) /home/attekett/firefox/objdir-ff-asan/js/src/../../dist/include/js/Utility.h:104
    #2 0x7f37df8b5563 in js::ArrayBufferObject::stealContents(JSContext*, JS::Handle<js::ArrayBufferObject*>) /home/attekett/firefox/js/src/vm/ArrayBufferObject.cpp:750
    #3 0x7f37df8b9d5f in JS_StealArrayBufferContents(JSContext*, JS::Handle<JSObject*>) /home/attekett/firefox/js/src/vm/ArrayBufferObject.cpp:1124
    #4 0x7f37dc48dd87 in mozilla::dom::StealJSArrayDataIntoThreadSharedFloatArrayBufferList(JSContext*, nsTArray<JSObject*> const&) /home/attekett/firefox/content/media/webaudio/AudioBuffer.cpp:223
    #5 0x7f37dc49094d in mozilla::dom::AudioBufferSourceNode::SendBufferParameterToStream(JSContext*) /home/attekett/firefox/content/media/webaudio/AudioBufferSourceNode.cpp:633
    #6 0x7f37da247406 in mozilla::dom::AudioBufferSourceNode::SetBuffer(JSContext*, mozilla::dom::AudioBuffer*) /home/attekett/firefox/objdir-ff-asan/dom/bindings/../../dist/include/mozilla/dom/AudioBufferSourceNode.h:56
    #7 0x7f37db141107 in mozilla::dom::GenericBindingSetter(JSContext*, unsigned int, JS::Value*) /home/attekett/firefox/dom/bindings/BindingUtils.cpp:2316
    #8 0x7f37df9e9c13 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) /home/attekett/firefox/js/src/jscntxtinlines.h:239
    #9 0x7f37df974ace in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) /home/attekett/firefox/js/src/vm/Interpreter.cpp:511
    #10 0x7f37df9eb9dd in js::InvokeGetterOrSetter(JSContext*, JSObject*, JS::Value, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) /home/attekett/firefox/js/src/vm/Interpreter.cpp:583
    #11 0x7f37df7ad310 in js::Shape::set(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSObject*>, bool, JS::MutableHandle<JS::Value>) /home/attekett/firefox/js/src/vm/Shape-inl.h:95
    #12 0x7f37df7aea18 in bool js::baseops::SetPropertyHelper<(js::ExecutionMode)0>(js::ExecutionModeTraits<(js::ExecutionMode)0>::ContextType, JS::Handle<JSObject*>, JS::Handle<JSObject*>, JS::Handle<jsid>, js::baseops::QualifiedBool, JS::MutableHandle<JS::Value>, bool) /home/attekett/firefox/js/src/jsobj.cpp:5069
    #13 0x7f37df9cf7cb in SetPropertyOperation(JSContext*, JS::Handle<JSScript*>, unsigned char*, JS::Handle<JS::Value>, JS::Handle<JS::Value>) /home/attekett/firefox/js/src/vm/Interpreter.cpp:314
    #14 0x7f37df9c056c in js::RunScript(JSContext*, js::RunState&) /home/attekett/firefox/js/src/vm/Interpreter.cpp:402
    #15 0x7f37df9ea161 in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) /home/attekett/firefox/js/src/vm/Interpreter.cpp:474
    #16 0x7f37df974ace in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) /home/attekett/firefox/js/src/vm/Interpreter.cpp:511
    #17 0x7f37df608875 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /home/attekett/firefox/js/src/jsapi.cpp:5210
    #18 0x7f37da6ce4cd in mozilla::dom::Function::Call(JSContext*, JS::Handle<JS::Value>, nsTArray<JS::Value> const&, mozilla::ErrorResult&) /home/attekett/firefox/objdir-ff-asan/dom/bindings/./FunctionBinding.cpp:34
    #19 0x7f37db771ebe in JS::Value mozilla::dom::Function::Call<nsCOMPtr<nsISupports> >(nsCOMPtr<nsISupports> const&, nsTArray<JS::Value> const&, mozilla::ErrorResult&, mozilla::dom::CallbackObject::ExceptionHandling) /home/attekett/firefox/objdir-ff-asan/dom/base/../../dist/include/mozilla/dom/FunctionBinding.h:58
    #20 0x7f37db747dd0 in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) /home/attekett/firefox/dom/base/nsGlobalWindow.cpp:12106
    #21 0x7f37db72c23a in nsGlobalWindow::RunTimeout(nsTimeout*) /home/attekett/firefox/dom/base/nsGlobalWindow.cpp:12330
    #22 0x7f37db74755f in nsGlobalWindow::TimerCallback(nsITimer*, void*) /home/attekett/firefox/dom/base/nsGlobalWindow.cpp:12576
    #23 0x7f37d8ab5390 in nsTimerImpl::Fire() /home/attekett/firefox/xpcom/threads/nsTimerImpl.cpp:609
    #24 0x7f37d8ab594e in nsTimerEvent::Run() /home/attekett/firefox/xpcom/threads/nsTimerImpl.cpp:702
    #25 0x7f37d8aade08 in nsThread::ProcessNextEvent(bool, bool*) /home/attekett/firefox/xpcom/threads/nsThread.cpp:766
    #26 0x7f37d8992e09 in NS_ProcessNextEvent(nsIThread*, bool) /home/attekett/firefox/xpcom/glue/nsThreadUtils.cpp:263
    #27 0x7f37d92b7384 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/attekett/firefox/ipc/glue/MessagePump.cpp:136
    #28 0x7f37d92461fe in MessageLoop::RunInternal() /home/attekett/firefox/ipc/chromium/src/base/message_loop.cc:229
    #29 0x7f37db35be2f in nsBaseAppShell::Run() /home/attekett/firefox/widget/xpwidgets/nsBaseAppShell.cpp:164

Thread T27 (MediaStreamGrph) created by T0 here:
    #0 0x423626 in __interceptor_pthread_create _asan_rtl_
    #1 0x7f37e414f81d in _PR_CreateThread /home/attekett/firefox/nsprpub/pr/src/pthreads/ptthread.c:453
    #2 0x7f37e414f39a in PR_CreateThread /home/attekett/firefox/nsprpub/pr/src/pthreads/ptthread.c:544
    #3 0x7f37d8aac31a in nsThread::Init() /home/attekett/firefox/xpcom/threads/nsThread.cpp:423
    #4 0x7f37d8ab06a8 in nsThreadManager::NewThread(unsigned int, unsigned int, nsIThread**) /home/attekett/firefox/xpcom/threads/nsThreadManager.cpp:248
    #5 0x7f37d8992605 in NS_NewThread(nsIThread**, nsIRunnable*, unsigned int) /home/attekett/firefox/xpcom/glue/nsThreadUtils.cpp:67
    #6 0x7f37dc41ba5c in tag_nsresult NS_NewNamedThread<16ul>(char const (&) [16ul], nsIThread**, nsIRunnable*, unsigned int) /home/attekett/firefox/objdir-ff-asan/content/media/../../dist/include/nsThreadUtils.h:75
    #7 0x7f37dc435c10 in mozilla::(anonymous namespace)::MediaStreamGraphStableStateRunnable::Run() /home/attekett/firefox/content/media/MediaStreamGraph.cpp:1580
    #8 0x7f37db35ce0d in nsCOMPtr_base::assign_assuming_AddRef(nsISupports*) /home/attekett/firefox/objdir-ff-asan/widget/xpwidgets/../../dist/include/nsCOMPtr.h:486
    #9 0x7f37db35d3cd in nsBaseAppShell::AfterProcessNextEvent(nsIThreadInternal*, unsigned int, bool) /home/attekett/firefox/widget/xpwidgets/nsBaseAppShell.h:93
    #10 0x7f37d8aae2ab in nsThread::ProcessNextEvent(bool, bool*) /home/attekett/firefox/xpcom/threads/nsThread.cpp:780
    #11 0x7f37d8992e09 in NS_ProcessNextEvent(nsIThread*, bool) /home/attekett/firefox/xpcom/glue/nsThreadUtils.cpp:263
    #12 0x7f37d92b73a5 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /home/attekett/firefox/ipc/glue/MessagePump.cpp:95
    #13 0x7f37d92461fe in MessageLoop::RunInternal() /home/attekett/firefox/ipc/chromium/src/base/message_loop.cc:229
    #14 0x7f37db35be2f in nsBaseAppShell::Run() /home/attekett/firefox/widget/xpwidgets/nsBaseAppShell.cpp:164
    #15 0x7f37ddc0e8b6 in nsAppStartup::Run() /home/attekett/firefox/toolkit/components/startup/nsAppStartup.cpp:278
    #16 0x7f37dda7eba8 in XREMain::XRE_mainRun() /home/attekett/firefox/toolkit/xre/nsAppRunner.cpp:4012
    #17 0x7f37dda7f849 in XREMain::XRE_main(int, char**, nsXREAppData const*) /home/attekett/firefox/toolkit/xre/nsAppRunner.cpp:4083
    #18 0x7f37dda8018b in XRE_main /home/attekett/firefox/toolkit/xre/nsAppRunner.cpp:4297
    #19 0x479fa6 in do_main(int, char**, nsIFile*) /home/attekett/firefox/browser/app/nsBrowserApp.cpp:282
    #20 0x7f37e66a276c in ?? ??:0

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 ??
Shadow bytes around the buggy address:
  0x0fe775b7b580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe775b7b590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe775b7b5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe775b7b5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe775b7b5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0fe775b7b5d0: 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
  0x0fe775b7b5e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fe775b7b5f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fe775b7b600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fe775b7b610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fe775b7b620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==6994==ABORTING
Marking sec-critical because Atte told me that he also gets a UAF from time to time.
Severity: normal → critical
Keywords: crash, csectype-bounds, sec-critical, testcase
(Assignee)

Comment 2

5 years ago
This looks like a bug introduced in changes from bug 937057 and so would affect versions back to 28.

The length of a memcpy is affected and would be > 2^31, but much smaller read and write buffers are allocated.  I don't see any UAF, except freed memory affected by the overflow.
Assignee: nobody → karlt
Status: NEW → ASSIGNED
status-firefox29: --- → affected
status-firefox30: --- → affected
status-firefox31: --- → affected
status-firefox32: --- → affected
status-firefox-esr24: --- → unaffected
(Assignee)

Comment 3

5 years ago
Created attachment 8434739 [details] [diff] [review]
reset mRemainingResamplerTail when no longer using the resampler
Attachment #8434739 - Flags: review?(paul)
(Assignee)

Comment 4

5 years ago
Leaving mRemainingResamplerTail set caused CopyFromBuffer() to be called when
past the buffer end, but that situation is only handled correctly when
mResampler is set.
Attachment #8434739 - Flags: review?(paul) → review+
tracking-firefox32: --- → +
(Assignee)

Comment 5

5 years ago
Created attachment 8435441 [details] [diff] [review]
patch for 28 branch

I don't know how much longer b2g28 will be supported, but this patch is for that branch.

The m-c patch should apply to branches back as far as 30.
(Assignee)

Comment 6

5 years ago
Created attachment 8435469 [details]
reduced testcase for crashtest
(Assignee)

Comment 7

5 years ago
Comment on attachment 8434739 [details] [diff] [review]
reset mRemainingResamplerTail when no longer using the resampler

[Security approval request comment]
How easily could an exploit be constructed based on the patch?

It is reasonably difficult.  It would require understanding of related code or considerable fuzz testing because exploiting requires careful timing of changes.
However, there is no need to rush landing this.  It can wait until closer to the next release.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?  No.

Which older supported branches are affected by this flaw? versions back to 28.

If not all supported branches, which bug introduced the flaw? bug 937057.

Do you have backports for the affected branches? Yes.

How likely is this patch to cause regressions; how much testing does it need?

The patch is simple and low risk.
Attachment #8434739 - Flags: sec-approval?
Whiteboard: [checkin on 7/1/14]
Comment on attachment 8434739 [details] [diff] [review]
reset mRemainingResamplerTail when no longer using the resampler

Sec-approval+ for trunk checkin on July 1, which is halfway through the next cycle.
Attachment #8434739 - Flags: sec-approval? → sec-approval+
status-firefox29: affected → wontfix
status-firefox33: --- → affected
tracking-firefox33: --- → +
status-firefox30: affected → wontfix
tracking-firefox31: --- → +
https://hg.mozilla.org/mozilla-central/rev/67ea04f01522
Status: ASSIGNED → RESOLVED
Last Resolved: 5 years ago
status-firefox33: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla33
(Assignee)

Comment 11

5 years ago
Comment on attachment 8434739 [details] [diff] [review]
reset mRemainingResamplerTail when no longer using the resampler

Approval Request Comment
[Feature/regressing bug #]: bug 937057.
[User impact if declined]: sec-critical
[Describe test coverage new/current, TBPL]: testcase not yet landed because of security risks.
[Risks and why]: The patch is simple and low risk.
[String/UUID change made/needed]: none
Attachment #8434739 - Flags: approval-mozilla-beta?
Attachment #8434739 - Flags: approval-mozilla-aurora?
(Assignee)

Updated

5 years ago
Whiteboard: [checkin on 7/1/14]
(Assignee)

Updated

5 years ago
status-b2g-v1.3: --- → affected
status-b2g-v1.4: --- → affected
Attachment #8434739 - Flags: approval-mozilla-beta?
Attachment #8434739 - Flags: approval-mozilla-beta+
Attachment #8434739 - Flags: approval-mozilla-aurora?
Attachment #8434739 - Flags: approval-mozilla-aurora+
Flags: sec-bounty?
https://hg.mozilla.org/releases/mozilla-aurora/rev/96f02035050d
https://hg.mozilla.org/releases/mozilla-beta/rev/1db524a4b295
https://hg.mozilla.org/releases/mozilla-b2g30_v1_4/rev/461d27660f96
https://hg.mozilla.org/releases/mozilla-b2g28_v1_3/rev/20f7440a1950
status-b2g-v1.3: affected → fixed
status-b2g-v1.3T: --- → affected
status-b2g-v1.4: affected → fixed
status-b2g-v2.0: --- → fixed
status-b2g-v2.1: --- → fixed
status-firefox31: affected → fixed
status-firefox32: affected → fixed
Reproduced the original issue using the POC from comment #0 with the following builds:

* firefox-33.0a1.en-US.mac [20140701030202] (crashed the browser when poc opened)
** http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2014-07-01-03-02-02-mozilla-central/
* firefox-32.0a1.en-US.linux-x86_64-asan [20140603145026] (reproduced the original issue from comment #0)
** http://inbound-archive.pub.build.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-central-linux64-asan/1401807026/

Went through m-c verification using the following builds:

* firefox-33.0a1.en-US.mac [20140707030202] (opened the poc several times without crashes)
** http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2014-07-07-03-02-02-mozilla-central/
* firefox-33.0a1.en-US.linux-x86_64-asan [20140707060822] (opened the poc several times without crashes)
** http://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-central-linux64-asan/1404738502/
status-firefox33: fixed → verified
status-b2g-v1.3T: affected → fixed
Flags: sec-bounty? → sec-bounty+
Keywords: sec-critical → sec-high
Went through aurora & beta verification using the following builds:

fx 32.0a2:
** http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2014-07-08-00-40-01-mozilla-aurora/ [PASSED]
** http://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-aurora-linux64-asan/1404826110/ [PASSED]

fx 31.0:
** http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/31.0b8/mac/ [PASSED]
** http://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/mozilla-beta-linux64-asan/1404763596/ [PASSED]

I ran both the original poc from comment #0 and the reduced poc from comment #6 without any issues
Status: RESOLVED → VERIFIED
status-firefox31: fixed → verified
status-firefox32: fixed → verified
Whiteboard: [adv-main31+]
Alias: CVE-2014-1549
Blocks: 937057
Keywords: regression
QA Whiteboard: [qa!]
(Assignee)

Updated

3 years ago
Group: core-security
You need to log in before you can comment on or make changes to this bug.