Heap-use-after-free in nsHTMLMediaElement::CaptureStreamInternal

RESOLVED FIXED

Status

()

Core
Audio/Video
--
critical
RESOLVED FIXED
6 years ago
2 years ago

People

(Reporter: Abhishek Arya, Unassigned)

Tracking

(5 keywords)

Trunk
x86_64
All
crash, csectype-uaf, reproducible, sec-high, testcase
Points:
---
Bug Flags:
sec-bounty +
in-testsuite ?

Firefox Tracking Flags

(firefox17 wontfix, firefox18 fixed, firefox19+ fixed, firefox-esr1718+ fixed, b2g18 fixed)

Details

(Whiteboard: [asan] fixed by 794426)

Attachments

(2 attachments)

(Reporter)

Description

6 years ago
Reproduces on trunk, testcase coming.

=================================================================
==8572== ERROR: AddressSanitizer heap-use-after-free on address 0x7ff0609a6788 at pc 0x7ff08c1d9180 bp 0x7ffff1561730 sp 0x7ffff1561728
READ of size 8 at 0x7ff0609a6788 thread T0
    #0 0x7ff08c1d917f in nsRefPtr<nsDOMMediaStream>::get() const src/../../../../dist/include/nsAutoPtr.h:1003
    #1 0x7ff08c2012d1 in nsRefPtr<nsDOMMediaStream>::operator->() const src/../../../../dist/include/nsAutoPtr.h:1023
    #2 0x7ff08c20098a in nsHTMLMediaElement::CaptureStreamInternal(bool) src/content/html/content/src/nsHTMLMediaElement.cpp:1536
    #3 0x7ff08c202011 in nsHTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/content/html/content/src/nsHTMLMediaElement.cpp:1550
    #4 0x7ff08c1c62f7 in nsHTMLAudioElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/../../../../dist/include/nsHTMLAudioElement.h:37
    #5 0x7ff08c1cf24e in non-virtual thunk to nsHTMLAudioElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/build/unix/stdc++compat/stdc++compat.cpp:0
    #6 0x7ff094299367 in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:162
    #7 0x7ff08f8ecbbe in CallMethodHelper::Invoke() src/js/xpconnect/src/XPCWrappedNative.cpp:3118
    #8 0x7ff08f94f855 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1480
    #9 0x7ff09add1ba1 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:389
    #10 0x7ff09ad5eab0 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2413
    #11 0x7ff09acc5a55 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:309
    #12 0x7ff09addeeb6 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:494
    #13 0x7ff09c205743 in EvalKernel(JSContext*, JS::CallArgs const&, EvalType, js::StackFrame*, JS::Handle<JSObject*>) src/js/src/builtin/Eval.cpp:284
    #14 0x7ff09c206ae2 in js::DirectEval(JSContext*, JS::CallArgs const&) src/js/src/builtin/Eval.cpp:334
    #15 0x7ff09c9d9030 in js::mjit::stubs::Eval(js::VMFrame&, unsigned int) src/js/src/methodjit/InvokeHelpers.cpp:393
    #16 0x7ff09c37300a in throwpoline_exit src/js/src/methodjit/MethodJIT.cpp:0
    #17 0x7ff09c375517 in js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, JS::Value*, bool) src/js/src/methodjit/MethodJIT.cpp:1016
    #18 0x7ff09c3770a0 in CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*, bool) src/js/src/methodjit/MethodJIT.cpp:1074
    #19 0x7ff09c3774f9 in js::mjit::JaegerShotAtSafePoint(JSContext*, void*, bool) src/js/src/methodjit/MethodJIT.cpp:1092
    #20 0x7ff09ace5545 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:1472
    #21 0x7ff09acc5a55 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:309
    #22 0x7ff09addeeb6 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:494
    #23 0x7ff09ade0e6e in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) src/js/src/jsinterp.cpp:531
    #24 0x7ff09a555414 in JS::Evaluate(JSContext*, JS::Handle<JSObject*>, JS::CompileOptions, unsigned short const*, unsigned long, JS::Value*) src/js/src/jsapi.cpp:5710
    #25 0x7ff09a55a3b1 in JS_EvaluateUCScriptForPrincipalsVersionOrigin src/js/src/jsapi.cpp:5791
    #26 0x7ff08ca9359f in nsJSContext::EvaluateString(nsAString_internal const&, JSObject*, nsIPrincipal*, nsIPrincipal*, char const*, unsigned int, JSVersion, nsAString_internal*, bool*) src/dom/base/nsJSEnvironment.cpp:1494
    #27 0x7ff08cc4314f in nsGlobalWindow::RunTimeoutHandler(nsTimeout*, nsIScriptContext*) src/dom/base/nsGlobalWindow.cpp:9624
    #28 0x7ff08cbfa8e9 in nsGlobalWindow::RunTimeout(nsTimeout*) src/dom/base/nsGlobalWindow.cpp:9885
    #29 0x7ff08cc411aa in nsGlobalWindow::TimerCallback(nsITimer*, void*) src/dom/base/nsGlobalWindow.cpp:10152
    #30 0x7ff0941d98d2 in nsTimerImpl::Fire() src/xpcom/threads/nsTimerImpl.cpp:473
    #31 0x7ff0941db188 in nsTimerEvent::Run() src/xpcom/threads/nsTimerImpl.cpp:556
    #32 0x7ff09419e57e in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:624
    #33 0x7ff093e3c927 in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:220
    #34 0x7ff092dfaad5 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:82
    #35 0x7ff09444b859 in MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:208
    #36 0x7ff09444b6a2 in MessageLoop::RunHandler() src/ipc/chromium/src/base/message_loop.cc:201
    #37 0x7ff09444b587 in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:175
    #38 0x7ff0922c7f0e in nsBaseAppShell::Run() src/widget/xpwidgets/nsBaseAppShell.cpp:163
    #39 0x7ff090f3f598 in nsAppStartup::Run() src/toolkit/components/startup/nsAppStartup.cpp:273
    #40 0x7ff08776bf90 in XREMain::XRE_mainRun() src/toolkit/xre/nsAppRunner.cpp:3800
    #41 0x7ff087772204 in XREMain::XRE_main(int, char**, nsXREAppData const*) src/toolkit/xre/nsAppRunner.cpp:3877
    #42 0x7ff0877752ce in XRE_main src/toolkit/xre/nsAppRunner.cpp:3953
    #43 0x40c5bb in do_main(int, char**) src/browser/app/nsBrowserApp.cpp:174
    #44 0x409e1f in main src/browser/app/nsBrowserApp.cpp:279
    #45 0x7ff0a4535c4d in ?? ??:0
0x7ff0609a6788 is located 8 bytes inside of 24-byte region [0x7ff0609a6780,0x7ff0609a6798)
freed by thread T0 here:
    #0 0x4c3d80 in free ??:0
    #1 0x7ff0a13d3572 in moz_free src/memory/mozalloc/mozalloc.cpp:51
    #2 0x7ff08798bac2 in nsTArrayInfallibleAllocator::Free(void*) src/../../dist/include/nsTArray.h:64
    #3 0x7ff08798b05c in nsTArray_base<nsTArrayDefaultAllocator>::ShrinkCapacity(unsigned int, unsigned long) src/../../dist/include/nsTArray-inl.h:207
    #4 0x7ff087989d2e in nsTArray_base<nsTArrayDefaultAllocator>::ShiftData(unsigned int, unsigned int, unsigned int, unsigned int, unsigned long) src/../../dist/include/nsTArray-inl.h:234
    #5 0x7ff08c22fdb9 in nsTArray<nsHTMLMediaElement::OutputMediaStream, nsTArrayDefaultAllocator>::RemoveElementsAt(unsigned int, unsigned int) src/../../../../dist/include/nsTArray.h:934
    #6 0x7ff08c1e080e in nsTArray<nsHTMLMediaElement::OutputMediaStream, nsTArrayDefaultAllocator>::Clear() src/../../../../dist/include/nsTArray.h:944
    #7 0x7ff08c1e0019 in nsHTMLMediaElement::ShutdownDecoder() src/content/html/content/src/nsHTMLMediaElement.cpp:563
    #8 0x7ff08c1e0c16 in nsHTMLMediaElement::AbortExistingLoads() src/content/html/content/src/nsHTMLMediaElement.cpp:579
    #9 0x7ff08c1e7a97 in nsHTMLMediaElement::Load() src/content/html/content/src/nsHTMLMediaElement.cpp:709
    #10 0x7ff08c1c32d5 in nsHTMLAudioElement::Load() src/../../../../dist/include/nsHTMLAudioElement.h:37
    #11 0x7ff08c1ceb8b in non-virtual thunk to nsHTMLAudioElement::Load() src/build/unix/stdc++compat/stdc++compat.cpp:0
    #12 0x7ff094299367 in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:162
    #13 0x7ff08f8ecbbe in CallMethodHelper::Invoke() src/js/xpconnect/src/XPCWrappedNative.cpp:3118
    #14 0x7ff08f94f855 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1480
    #15 0x7ff09add1ba1 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:389
    #16 0x7ff09ad5eab0 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2413
    #17 0x7ff09acc5a55 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:309
    #18 0x7ff09addeeb6 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:494
    #19 0x7ff09c205743 in EvalKernel(JSContext*, JS::CallArgs const&, EvalType, js::StackFrame*, JS::Handle<JSObject*>) src/js/src/builtin/Eval.cpp:284
    #20 0x7ff09c206ae2 in js::DirectEval(JSContext*, JS::CallArgs const&) src/js/src/builtin/Eval.cpp:334
    #21 0x7ff09c9d9030 in js::mjit::stubs::Eval(js::VMFrame&, unsigned int) src/js/src/methodjit/InvokeHelpers.cpp:393
    #22 0x7ff07115d6f4 in  
    #23 0x7ff09c375517 in js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, JS::Value*, bool) src/js/src/methodjit/MethodJIT.cpp:1016
    #24 0x7ff09c3770a0 in CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*, bool) src/js/src/methodjit/MethodJIT.cpp:1074
    #25 0x7ff09c3769d7 in js::mjit::JaegerShot(JSContext*, bool) src/js/src/methodjit/MethodJIT.cpp:1086
    #26 0x7ff09ad633ae in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2453
    #27 0x7ff09acc5a55 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:309
    #28 0x7ff09addeeb6 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:494
    #29 0x7ff09ade0e6f in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) src/js/src/jsinterp.cpp:531
previously allocated by thread T0 here:
    #0 0x4c3e40 in __interceptor_malloc ??:0
    #1 0x7ff0a13d36c6 in moz_xmalloc src/memory/mozalloc/mozalloc.cpp:57
    #2 0x7ff087987432 in nsTArrayInfallibleAllocator::Malloc(unsigned long) src/../../dist/include/nsTArray.h:56
    #3 0x7ff0879852ed in nsTArray_base<nsTArrayDefaultAllocator>::EnsureCapacity(unsigned int, unsigned int) src/../../dist/include/nsTArray-inl.h:119
    #4 0x7ff08c22dab0 in nsTArray<nsHTMLMediaElement::OutputMediaStream, nsTArrayDefaultAllocator>::AppendElements(unsigned int) src/../../../../dist/include/nsTArray.h:891
    #5 0x7ff08c200e17 in nsTArray<nsHTMLMediaElement::OutputMediaStream, nsTArrayDefaultAllocator>::AppendElement() src/../../../../dist/include/nsTArray.h:906
    #6 0x7ff08c20057f in nsHTMLMediaElement::CaptureStreamInternal(bool) src/content/html/content/src/nsHTMLMediaElement.cpp:1526
    #7 0x7ff08c202011 in nsHTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/content/html/content/src/nsHTMLMediaElement.cpp:1550
    #8 0x7ff08c1c62f7 in nsHTMLAudioElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/../../../../dist/include/nsHTMLAudioElement.h:37
    #9 0x7ff08c1cf24e in non-virtual thunk to nsHTMLAudioElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) src/build/unix/stdc++compat/stdc++compat.cpp:0
    #10 0x7ff094299367 in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:162
    #11 0x7ff08f8ecbbe in CallMethodHelper::Invoke() src/js/xpconnect/src/XPCWrappedNative.cpp:3118
    #12 0x7ff08f94f855 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1480
    #13 0x7ff09add1ba1 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:389
    #14 0x7ff09ad5eab0 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2413
    #15 0x7ff09acc5a55 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:309
    #16 0x7ff09addeeb6 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) src/js/src/jsinterp.cpp:494
    #17 0x7ff09c205743 in EvalKernel(JSContext*, JS::CallArgs const&, EvalType, js::StackFrame*, JS::Handle<JSObject*>) src/js/src/builtin/Eval.cpp:284
    #18 0x7ff09c206ae2 in js::DirectEval(JSContext*, JS::CallArgs const&) src/js/src/builtin/Eval.cpp:334
    #19 0x7ff09c9d9030 in js::mjit::stubs::Eval(js::VMFrame&, unsigned int) src/js/src/methodjit/InvokeHelpers.cpp:393
    #20 0x7ff07115d6f4 in  
    #21 0x7ff09c375517 in js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, JS::Value*, bool) src/js/src/methodjit/MethodJIT.cpp:1016
    #22 0x7ff09c3770a0 in CheckStackAndEnterMethodJIT(JSContext*, js::StackFrame*, void*, bool) src/js/src/methodjit/MethodJIT.cpp:1074
    #23 0x7ff09c3774f9 in js::mjit::JaegerShotAtSafePoint(JSContext*, void*, bool) src/js/src/methodjit/MethodJIT.cpp:1092
    #24 0x7ff09ace5546 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:1472
Shadow byte and word:
  0x1ffe0c134cf1: fd
  0x1ffe0c134cf0: fd fd fd fd fd fd fd fd
More shadow bytes:
  0x1ffe0c134cd0: fd fd fd fd fd fd fd fd
  0x1ffe0c134cd8: fd fd fd fd fd fd fd fd
  0x1ffe0c134ce0: fa fa fa fa fa fa fa fa
  0x1ffe0c134ce8: fa fa fa fa fa fa fa fa
=>0x1ffe0c134cf0: fd fd fd fd fd fd fd fd
  0x1ffe0c134cf8: fd fd fd fd fd fd fd fd
  0x1ffe0c134d00: fa fa fa fa fa fa fa fa
  0x1ffe0c134d08: fa fa fa fa fa fa fa fa
  0x1ffe0c134d10: 00 00 00 00 fb fb fb fb
Stats: 274M malloced (291M for red zones) by 467459 calls
Stats: 41M realloced by 26550 calls
Stats: 232M freed by 312131 calls
Stats: 97M really freed by 181036 calls
Stats: 456M (116819 full pages) mmaped in 114 calls
  mmaps   by size class: 8:245745; 9:40955; 10:16380; 11:14329; 12:4096; 13:2560; 14:1280; 15:256; 16:448; 17:1248; 18:192; 19:40; 20:16;
  mallocs by size class: 8:354761; 9:59447; 10:21309; 11:20690; 12:3786; 13:2988; 14:1730; 15:408; 16:579; 17:1498; 18:206; 19:41; 20:16;
  frees   by size class: 8:220589; 9:48134; 10:17220; 11:17141; 12:2688; 13:2372; 14:1476; 15:365; 16:497; 17:1484; 18:114; 19:39; 20:12;
  rfrees  by size class: 8:134988; 9:23860; 10:9148; 11:9537; 12:864; 13:718; 14:742; 15:165; 16:345; 17:642; 18:22; 19:4; 20:1;
Stats: malloc large: 1761 small slow: 2415
==8572== ABORTING
(Reporter)

Comment 1

6 years ago
Minimizing testcase is not working since it is timing dependent. However, the fuzzed testcase reliably reproduces on my local machine. I can test out any potential fix you have in mind.

1524 nsHTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
1525 {
1526   OutputMediaStream* out = mOutputStreams.AppendElement();
1527   out->mStream = nsDOMMediaStream::CreateInputStream();

Looks like nsDOMMediaStream(out->mStream) becomes stale as soon as we leave the function since OutputMediaStream is the last one holding the ref.
(Reporter)

Comment 2

6 years ago
Created attachment 654699 [details]
Testcase

Finally have a reduction. Problems - very few times crashes near null, sometimes just corrupts profile, so need to delete it and retry.
Crashes also a non-ASAN Linux64 debug build.
Severity: normal → critical
Component: General → Video/Audio
Keywords: crash, reproducible, testcase
Product: Firefox → Core
Whiteboard: [asan]
Robert, can you find someone to look at this one?
Assignee: nobody → roc
I was not able to reproduce the bug on a regular Windows build. This code has changed quite a bit since the bug was filed, too. I wonder if this is still reproducible?

I did find a different bug, which I have filed as bug 794426, with a fix. I don't think that fix will fix this bug though.

(In reply to Abhishek Arya from comment #1)
> 1524 nsHTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
> 1525 {
> 1526   OutputMediaStream* out = mOutputStreams.AppendElement();
> 1527   out->mStream = nsDOMMediaStream::CreateInputStream();
> 
> Looks like nsDOMMediaStream(out->mStream) becomes stale as soon as we leave
> the function since OutputMediaStream is the last one holding the ref.

I don't understand this comment. mOutputStreams is part of the nsHTMLMediaElement, and 'out' is an element of that array. So we should be keeping out->mStream alive as long as the element survives (and the 'out' element is not removed from the array).

Anyway, the error report looks like the problem was an out-of-bounds array access, not a problem accessing a stale nsDOMMediaStream.
(Reporter)

Comment 6

6 years ago
This reproduces on trunk on an asanified linux build. You just need to run multiple firefox instances at once simultaneously using an automated script.
Robert, can you suggest a security rating here?
Keywords: sec-critical
(In reply to Abhishek Arya from comment #6)
> You just need to run multiple firefox instances at once simultaneously

I don't understand how this matters. Running low on memory? Keeps the machine busy and thus changes timing relations?
(Reporter)

Comment 10

6 years ago
(In reply to Daniel Veditz [:dveditz] from comment #9)
> (In reply to Abhishek Arya from comment #6)
> > You just need to run multiple firefox instances at once simultaneously
> 
> I don't understand how this matters. Running low on memory? Keeps the
> machine busy and thus changes timing relations?

So, the repro has this line setTimeout("CFcrash()", 378); where CFCrash() calls the api mozCaptureStreamUntilEnded. i think it depends on the right time to trigger this api, for 70-80% of the time it will crash on a null for this repro. So, if play with the number of firefox instances and timeout value, you will have atleast > 1 instance hitting the use-after-free crash. i just did a quick run against yesterday's build with 15 instances and i reproduce the UAF in two instances .
Created attachment 676234 [details]
ASAN dump on Linux64 with test loaded in several tabs

I got a slightly different stack when loading up the test in several tabs.
Lowering the severity to "high" to reflect the apparent unreliability of exploiting this. But it's still serious.
status-firefox17: --- → wontfix
status-firefox18: --- → affected
status-firefox19: --- → affected
tracking-firefox19: --- → +
Flags: sec-bounty?
Keywords: sec-critical → sec-high

Comment 13

6 years ago
This is a sec-high (or -crit I guess if we find a realiable variant) with a testcase, and it's marked tracking for 19.
roc, any chance we can get some traction here?
Mats' stacks are helpful. This is a huge problem:

    #13 0x7fd4e473e0c0 in NS_ProcessNextEvent_P(nsIThread*, bool) xpcom/build/nsThreadUtils.cpp:220
    #14 0x7fd4e4b02e14 in nsThread::Shutdown() xpcom/threads/nsThread.cpp:467
    #15 0x7fd4dec0b030 in nsBuiltinDecoderStateMachine::StopAudioThread() content/media/nsBuiltinDecoderStateMachine.cpp:1550
    #16 0x7fd4dec0aa4f in nsBuiltinDecoderStateMachine::SetAudioCaptured(bool) content/media/nsBuiltinDecoderStateMachine.cpp:1336
    #17 0x7fd4debb4868 in nsBuiltinDecoder::SetAudioCaptured(bool) content/media/nsBuiltinDecoder.cpp:60
    #18 0x7fd4dc5b7dc9 in nsHTMLMediaElement::CaptureStreamInternal(bool) content/html/content/src/nsHTMLMediaElement.cpp:1552
    #19 0x7fd4dc5b9362 in nsHTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) content/html/content/src/nsHTMLMediaElement.cpp:1567
    #20 0x7fd4dc575788 in nsHTMLAudioElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream**) ../../../../dist/include/nsHTMLAudioElement.h:37

We shouldn't be spinning the event loop under this DOM API call! Bug 794426 is basically about this too.
Assignee: roc → paul

Comment 15

6 years ago
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #14)
> We shouldn't be spinning the event loop under this DOM API call! Bug 794426
> is basically about this too.

Does that mean the patch from there helps for this security bug here as well?
Bug 794426 has landed on central now, please confirm if the expected results resolve this bug and if not, what the next steps are.
(Reporter)

Comment 18

6 years ago
(In reply to Lukas Blakk [:lsblakk] from comment #17)
> Bug 794426 has landed on central now, please confirm if the expected results
> resolve this bug and if not, what the next steps are.

Verified that the security crash does not reproduce anymore on trunk. I did recheck that it reproduced fine on my old build.

However, the testcase crashes on a null. It can be tracked in a separate functional bug.

>=================================================================
>==30345== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fc6ddb4caaf sp 0x7fc6a178f340 bp 0x7fc6a178f4d0 T36)
>AddressSanitizer can not provide additional info.
>    #0 0x7fc6ddb4caae in mozilla::MediaDecoder::UpdatePlaybackOffset(long) src/content/media/MediaDecoder.cpp:1330
>    #1 0x7fc6ddb85da7 in mozilla::MediaDecoderStateMachine::PlayFromAudioQueue(unsigned long, unsigned int) src/content/media/MediaDecoderStateMachine.cpp:1213
>    #2 0x7fc6ddb823c3 in mozilla::MediaDecoderStateMachine::AudioLoop() src/content/media/MediaDecoderStateMachine.cpp:1082
>    #3 0x7fc6ddba237e in nsRunnableMethodImpl<void (mozilla::MediaDecoderStateMachine::*)(), true>::Run() src/../../dist/include/nsThreadUtils.h:367
>    #4 0x7fc6e479a21e in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:627
>    #5 0x7fc6e4410e5f in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:237
>    #6 0x7fc6e4791eb4 in nsThread::ThreadFunc(void*) src/xpcom/threads/nsThread.cpp:265
>    #7 0x7fc6f673b286 in _pt_root src/nsprpub/pr/src/pthreads/ptthread.c:156
>    #8 0x4c71aa in __asan::AsanThread::ThreadStart()
>Thread T36 created by T14 here:
>    #0 0x4bff24 in __interceptor_pthread_create
>    #1 0x7fc6f672c635 in _PR_CreateThread src/nsprpub/pr/src/pthreads/ptthread.c:393
>    #2 0x7fc6f672a426 in PR_CreateThread src/nsprpub/pr/src/pthreads/ptthread.c:476
>    #3 0x7fc6e4794f40 in nsThread::Init() src/xpcom/threads/nsThread.cpp:331
>    #4 0x7fc6e47ac7c8 in nsThreadManager::NewThread(unsigned int, unsigned int, nsIThread**) src/xpcom/threads/nsThreadManager.cpp:215
>    #5 0x7fc6e440e5d1 in NS_NewThread_P(nsIThread**, nsIRunnable*, unsigned int) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:66
>    #6 0x7fc6ddb6517b in tag_nsresult NS_NewNamedThread_P<12ul>(char const (&) [12ul], nsIThread**, nsIRunnable*, unsigned int) src/../../dist/include/nsThreadUtils.h:90
>    #7 0x7fc6ddb88475 in mozilla::MediaDecoderStateMachine::StartAudioThread() src/content/media/MediaDecoderStateMachine.cpp:1669
>    #8 0x7fc6ddb87eeb in mozilla::MediaDecoderStateMachine::StartPlayback() src/content/media/MediaDecoderStateMachine.cpp:1258
>    #9 0x7fc6ddb977bb in mozilla::MediaDecoderStateMachine::AdvanceFrame() src/content/media/MediaDecoderStateMachine.cpp:2365
>    #10 0x7fc6ddb947ba in mozilla::MediaDecoderStateMachine::RunStateMachine() src/content/media/MediaDecoderStateMachine.cpp:2078
>    #11 0x7fc6ddb9de63 in mozilla::MediaDecoderStateMachine::CallRunStateMachine() src/content/media/MediaDecoderStateMachine.cpp:2578
>    #12 0x7fc6ddb9d7cf in mozilla::MediaDecoderStateMachine::Run() src/content/media/MediaDecoderStateMachine.cpp:2555
>    #13 0x7fc6e479a21e in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:627
>    #14 0x7fc6e4410e5f in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:237
>    #15 0x7fc6e4791eb4 in nsThread::ThreadFunc(void*) src/xpcom/threads/nsThread.cpp:265
>    #16 0x7fc6f673b286 in _pt_root src/nsprpub/pr/src/pthreads/ptthread.c:156
>    #17 0x4c71aa in __asan::AsanThread::ThreadStart()
>Thread T14 created by T0 here:
>    #0 0x4bff24 in __interceptor_pthread_create
>    #1 0x7fc6f672c635 in _PR_CreateThread src/nsprpub/pr/src/pthreads/ptthread.c:393
>    #2 0x7fc6f672a426 in PR_CreateThread src/nsprpub/pr/src/pthreads/ptthread.c:476
>    #3 0x7fc6e4794f40 in nsThread::Init() src/xpcom/threads/nsThread.cpp:331
>    #4 0x7fc6e47ac7c8 in nsThreadManager::NewThread(unsigned int, unsigned int, nsIThread**) src/xpcom/threads/nsThreadManager.cpp:215
>    #5 0x7fc6e440e5d1 in NS_NewThread_P(nsIThread**, nsIRunnable*, unsigned int) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:66
>    #6 0x7fc6ddb6517b in tag_nsresult NS_NewNamedThread_P<12ul>(char const (&) [12ul], nsIThread**, nsIRunnable*, unsigned int) src/../../dist/include/nsThreadUtils.h:90
>    #7 0x7fc6ddb64d41 in mozilla::StateMachineTracker::EnsureGlobalStateMachine() src/content/media/MediaDecoderStateMachine.cpp:243
>    #8 0x7fc6ddb68fb7 in mozilla::MediaDecoderStateMachine::MediaDecoderStateMachine(mozilla::MediaDecoder*, mozilla::MediaDecoderReader*, bool) src/content/media/MediaDecoderStateMachine.cpp:394
>    #9 0x7fc6ddd94f5b in mozilla::WaveDecoder::CreateStateMachine() src/content/media/wave/WaveDecoder.cpp:14
>    #10 0x7fc6ddb38390 in mozilla::MediaDecoder::Load(mozilla::MediaResource*, nsIStreamListener**, mozilla::MediaDecoder*) src/content/media/MediaDecoder.cpp:421
>    #11 0x7fc6db5be39c in nsHTMLMediaElement::FinishDecoderSetup(mozilla::MediaDecoder*, mozilla::MediaResource*, nsIStreamListener**, mozilla::MediaDecoder*) src/content/html/content/src/nsHTMLMediaElement.cpp:2320
>    #12 0x7fc6db57bf7f in nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel*, nsIStreamListener**) src/content/html/content/src/nsHTMLMediaElement.cpp:2293
>    #13 0x7fc6db57a614 in nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest*, nsISupports*) src/content/html/content/src/nsHTMLMediaElement.cpp:362
>    #14 0x7fc6d5ba9ae0 in nsBaseChannel::OnStartRequest(nsIRequest*, nsISupports*) src/netwerk/base/src/nsBaseChannel.cpp:720
>    #15 0x7fc6d5baae5a in non-virtual thunk to nsBaseChannel::OnStartRequest(nsIRequest*, nsISupports*) src/netwerk/base/src/nsBaseChannel.cpp:722
>    #16 0x7fc6d5c599b9 in nsInputStreamPump::OnStateStart() src/netwerk/base/src/nsInputStreamPump.cpp:417
>    #17 0x7fc6d5c58b51 in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) src/netwerk/base/src/nsInputStreamPump.cpp:368
>    #18 0x7fc6d5c5c246 in non-virtual thunk to nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) src/netwerk/base/src/nsInputStreamPump.cpp:397
>    #19 0x7fc6e467bcd5 in nsInputStreamReadyEvent::Run() src/xpcom/io/nsStreamUtils.cpp:82
>    #20 0x7fc6e479a21e in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:627
>    #21 0x7fc6e4410e5f in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:237
>    #22 0x7fc6e272e346 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:82
>    #23 0x7fc6e4a8718e in MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:215
>    #24 0x7fc6e4a86fd5 in MessageLoop::RunHandler() src/ipc/chromium/src/base/message_loop.cc:208
>    #25 0x7fc6e4a86ebb in MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:182
>    #26 0x7fc6e1b2bc94 in nsBaseAppShell::Run() src/widget/xpwidgets/nsBaseAppShell.cpp:163
>    #27 0x7fc6e0672922 in nsAppStartup::Run() src/toolkit/components/startup/nsAppStartup.cpp:289
>    #28 0x7fc6d5a407a4 in XREMain::XRE_mainRun() src/toolkit/xre/nsAppRunner.cpp:3824
>    #29 0x7fc6d5a46479 in XREMain::XRE_main(int, char**, nsXREAppData const*) src/toolkit/xre/nsAppRunner.cpp:3891
>    #30 0x7fc6d5a491f0 in XRE_main src/toolkit/xre/nsAppRunner.cpp:4089
>    #31 0x40c626 in do_main(int, char**) src/browser/app/nsBrowserApp.cpp:174
>    #32 0x409e60 in main src/browser/app/nsBrowserApp.cpp:279
>    #33 0x7fc6f69bc76c in
>Stats: 292M malloced (262M for red zones) by 597695 calls
>Stats: 48M realloced by 29479 calls
>Stats: 256M freed by 353851 calls
>Stats: 221M really freed by 281683 calls
>Stats: 240M (61653 full pages) mmaped in 458 calls
>  mmaps   by size class: 6:155629; 7:131040; 8:34799; 9:12276; 10:5110; 11:6885; 12:1536; 13:1152; 14:544; 15:224; 16:736; 17:460; 18:34; 19:35; 20:21;
>  mallocs by size class: 6:283639; 7:171224; 8:81058; 9:22703; 10:9775; 11:17991; 12:3053; 13:2398; 14:1836; 15:466; 16:1947; 17:1466; 18:74; 19:42; 20:23;
>  frees   by size class: 6:179123; 7:60327; 8:65374; 9:17061; 10:6721; 11:15871; 12:2167; 13:1946; 14:1622; 15:331; 16:1744; 17:1444; 18:61; 19:39; 20:20;
>  rfrees  by size class: 6:142776; 7:47183; 8:49396; 9:14813; 10:5327; 11:14698; 12:1713; 13:1330; 14:1413; 15:281; 16:1294; 17:1351; 18:51; 19:38; 20:19;
>Stats: malloc large: 4018 small slow: 5705
>==30345== ABORTING
>
>
>
Whiteboard: [asan] → [asan] fixed by 794426
Status: NEW → RESOLVED
Last Resolved: 6 years ago
Resolution: --- → FIXED

Comment 20

6 years ago
Bug 794426 is fixed on 19 as well, can we verify it also fixed this bug on that branch and mark the flags accordingly?
(In reply to Robert Kaiser (:kairo@mozilla.com) from comment #20)
> Bug 794426 is fixed on 19 as well, can we verify it also fixed this bug on
> that branch and mark the flags accordingly?

Matt, can you look at this on branch?
Flags: needinfo?(mwobensmith)
I can verify that the original crash no longer happens on Aurora 19, ASan build 2012-12-28. However, I can repro the secondary null crash that Abhishek mentions above.

Abhishek, have you filed a separate bug for that? Or shall I?
status-firefox19: affected → fixed
Flags: needinfo?(mwobensmith)
(Reporter)

Comment 23

6 years ago
(In reply to Matt Wobensmith from comment #22)
> I can verify that the original crash no longer happens on Aurora 19, ASan
> build 2012-12-28. However, I can repro the secondary null crash that
> Abhishek mentions above.
> 
> Abhishek, have you filed a separate bug for that? Or shall I?

Please feel free to file the null crasher functional bug. I haven't filed it yet.
Flags: sec-bounty? → sec-bounty+
Can this be put in testsuite?
Flags: in-testsuite?
I don't think so since it needs an ASAN build.
status-b2g18: --- → fixed
status-firefox18: affected → fixed
status-firefox-esr17: --- → fixed
tracking-firefox-esr17: --- → 18+
Group: core-security
Keywords: csectype-uaf
You need to log in before you can comment on or make changes to this bug.