Closed Bug 1020205 (CVE-2014-1549) Opened 10 years ago Closed 10 years ago

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

Categories

(Core :: Web Audio, defect)

x86_64
Linux
defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla33
Tracking Status
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

People

(Reporter: attekett, Assigned: karlt)

References

Details

(5 keywords, Whiteboard: [adv-main31+])

Attachments

(4 files)

Attached file 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
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
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+
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.
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+
https://hg.mozilla.org/mozilla-central/rev/67ea04f01522
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla33
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?
Whiteboard: [checkin on 7/1/14]
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?
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/
Flags: sec-bounty? → sec-bounty+
Keywords: sec-criticalsec-high
Whiteboard: [adv-main31+]
Alias: CVE-2014-1549
Blocks: 937057
Keywords: regression
QA Whiteboard: [qa!]
Group: core-security
You need to log in before you can comment on or make changes to this bug.