Closed Bug 1532553 (CVE-2019-9819) Opened 1 year ago Closed 1 year ago

Compartment mismatch in APIUnwrapAndDowncast<js::ReadableStream>

Categories

(Core :: DOM: Service Workers, defect, P2)

67 Branch
defect

Tracking

()

VERIFIED FIXED
mozilla67
Tracking Status
firefox-esr60 67+ fixed
firefox65 --- wontfix
firefox66 --- wontfix
firefox67 + verified
firefox68 + verified

People

(Reporter: nils, Assigned: baku, NeedInfo)

References

(Regression)

Details

(Keywords: regression, sec-high, Whiteboard: [post-critsmash-triage][adv-main67+][adv-esr60.7+])

Attachments

(4 files)

The following testcase crashes the latest ASAN build of Firefox 67.0a1 (SourceStamp=c59f0f40e0f6995c2bf70499e783afc7626cab96). It requires to be served from a localhost http server.

crash.html:
<script>
function start() {
o16=window.open('data:image/svg%2bxml,%3Csvg%3e');
o304=o16.caches;
o305=o304.open('c2');
o305.then(fun0);
}
function fun0(o340) {
o663=new Response('x');
o663.body;
o841=new Request('x');
o340.put(o841,o663);
}
</script>
<body onload="start()"></body>

ASAN output:
AddressSanitizer:DEADLYSIGNAL

==24009==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x563e39c30581 bp 0x7ffe45414eb0 sp 0x7ffe45414eb0 T0)
==24009==The signal is caused by a WRITE memory access.
==24009==Hint: address points to the zero page.
#0 0x563e39c30580 in MOZ_Crash(char const*, int, char const*) /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/Assertions.h:314:3
#1 0x563e39c3048d in MOZ_CrashPrintf /builds/worker/workspace/build/src/mfbt/Assertions.cpp:55:3
#2 0x7f0e211519ae in fail /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:43:5
#3 0x7f0e211519ae in check /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:59
#4 0x7f0e211519ae in check /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:73
#5 0x7f0e211519ae in checkImpl<JSObject > /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:184
#6 0x7f0e211519ae in check<JSObject > /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:192
#7 0x7f0e211519ae in APIUnwrapAndDowncast<js::ReadableStream> /builds/worker/workspace/build/src/js/src/builtin/Stream.cpp:4495
#8 0x7f0e211519ae in JS::ReadableStreamGetMode(JSContext
, JS::Handle<JSObject
>, JS::ReadableStreamMode*) /builds/worker/workspace/build/src/js/src/builtin/Stream.cpp:4558
#9 0x7f0e19c9c964 in mozilla::dom::FetchBody<mozilla::dom::Response>::SetBodyUsed(JSContext*, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/fetch/Fetch.cpp:1072:10
#10 0x7f0e19477747 in mozilla::dom::cache::TypeUtils::ToCacheResponse(JSContext*, mozilla::dom::cache::CacheResponse&, mozilla::dom::Response&, nsTArray<mozilla::UniquePtr<mozilla::ipc::AutoIPCStream, mozilla::DefaultDelete<mozilla::ipc::AutoIPCStream> > >&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/cache/TypeUtils.cpp:225:9
#11 0x7f0e193db496 in mozilla::dom::cache::AutoChildOpArgs::Add(JSContext*, mozilla::dom::InternalRequest*, mozilla::dom::cache::TypeUtils::BodyAction, mozilla::dom::cache::TypeUtils::SchemeAction, mozilla::dom::Response&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/cache/AutoUtils.cpp:306:21
#12 0x7f0e193e6d6f in mozilla::dom::cache::Cache::Put(JSContext*, mozilla::dom::RequestOrUSVString const&, mozilla::dom::Response&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/cache/Cache.cpp:420:8
#13 0x7f0e17af708c in put /builds/worker/workspace/build/src/obj-firefox/dom/bindings/CacheBinding.cpp:915:45
#14 0x7f0e17af708c in mozilla::dom::Cache_Binding::put_promiseWrapper(JSContext*, JS::Handle<JSObject*>, mozilla::dom::cache::Cache*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/CacheBinding.cpp:931
#15 0x7f0e19388255 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3144:13
#16 0x7f0e209e6f97 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:440:13
#17 0x7f0e209e6f97 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:532
#18 0x7f0e209e9552 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:603:8
#19 0x7f0e216a35e1 in js::ForwardingProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:162:10
#20 0x7f0e2165c4b1 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:238:19
#21 0x7f0e21681d90 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:503:19
#22 0x7f0e209e7fe9 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:506:14
#23 0x7f0e209ced3f in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:591:10
#24 0x7f0e209ced3f in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3055
#25 0x7f0e209b19b8 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:420:10
#26 0x7f0e209e7906 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:560:13
#27 0x7f0e209e9552 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:603:8
#28 0x7f0e216a35e1 in js::ForwardingProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/Wrapper.cpp:162:10
#29 0x7f0e2165c4b1 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const /builds/worker/workspace/build/src/js/src/proxy/CrossCompartmentWrapper.cpp:238:19
#30 0x7f0e21681d90 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) /builds/worker/workspace/build/src/js/src/proxy/Proxy.cpp:503:19
#31 0x7f0e209e7fe9 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:506:14
#32 0x7f0e209e9552 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:603:8
#33 0x7f0e20b9ba61 in Call /builds/worker/workspace/build/src/js/src/vm/Interpreter.h:98:10
#34 0x7f0e20b9ba61 in PromiseReactionJob(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/builtin/Promise.cpp:1660
#35 0x7f0e209e6f97 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:440:13
#36 0x7f0e209e6f97 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:532
#37 0x7f0e209e9552 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:603:8
#38 0x7f0e215cbe56 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/workspace/build/src/js/src/jsapi.cpp:2623:10
#39 0x7f0e171ef37c in mozilla::dom::PromiseJobCallback::Call(JSContext*, JS::Handle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/PromiseBinding.cpp:26:8
#40 0x7f0e11a5222f in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:91:12
#41 0x7f0e11a5222f in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:104
#42 0x7f0e11a5222f in mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:235
#43 0x7f0e11a2388e in mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:595:17
#44 0x7f0e11a2442a in mozilla::CycleCollectedJSContext::AfterProcessTask(unsigned int) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:437:3
#45 0x7f0e14040b75 in XPCJSContext::AfterProcessTask(unsigned int) /builds/worker/workspace/build/src/js/xpconnect/src/XPCJSContext.cpp:1261:28
#46 0x7f0e11cb501f in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1226:24
#47 0x7f0e11cbbfbd in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:482:10
#48 0x7f0e12f38b7f in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:88:21
#49 0x7f0e12e2032e in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#50 0x7f0e12e2032e in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#51 0x7f0e12e2032e in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#52 0x7f0e1c1cca13 in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:137:27
#53 0x7f0e2070586e in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:911:20
#54 0x7f0e12e2032e in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:315:10
#55 0x7f0e12e2032e in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:308
#56 0x7f0e12e2032e in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:290
#57 0x7f0e207049c3 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:749:34
#58 0x563e39bbc874 in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:49:28
#59 0x563e39bbc874 in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:265
#60 0x7f0e35594b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
#61 0x563e39ae1efc in _start (/home/nils/browser/firefox/firefox/firefox+0x2defc)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/Assertions.h:314:3 in MOZ_Crash(char const*, int, char const*)
==24009==ABORTING

Attached file asan.txt
Group: core-security → dom-core-security

Might be related to bug 1484524.

Priority: -- → P2

This looks like a compartment mismatch in stream code. Can you take a look, Jason? I'm not sure if this should be in JS or DOM.

Flags: needinfo?(jorendorff)
Keywords: sec-high
Summary: Assertion in APIUnwrapAndDowncast<js::ReadableStream> → Compartment mismatch in APIUnwrapAndDowncast<js::ReadableStream>
Assignee: nobody → jorendorff

Slightly reluctant to reproduce. Opening the data: url causes Firefox to pop up a dialog; sometimes the content process crashes, sometimes not.

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff6948aeae libsystem_kernel.dylib`__semwait_signal + 10
    frame #1: 0x00007fff69415830 libsystem_c.dylib`nanosleep + 199
    frame #2: 0x00007fff69415692 libsystem_c.dylib`sleep + 41
    frame #3: 0x0000000119d6c6c4 XUL`js::ContextChecks::check(JSObject*, int) [inlined] js::ContextChecks::fail(c1=<unavailable>, c2=<unavailable>, argIndex=<unavailable>) at JSContext-inl.h:44 [opt]
    frame #4: 0x0000000119d6c697 XUL`js::ContextChecks::check(JSObject*, int) [inlined] js::ContextChecks::check(this=<unavailable>, c=<unavailable>, argIndex=<unavailable>) at JSContext-inl.h:61 [opt]
    frame #5: 0x0000000119d6c694 XUL`js::ContextChecks::check(this=<unavailable>, obj=0x00000f1cf9046c68, argIndex=0) at JSContext-inl.h:75 [opt]
    frame #6: 0x0000000119eb4064 XUL`JS::ReadableStreamGetMode(JSContext*, JS::Handle<JSObject*>, JS::ReadableStreamMode*) [inlined] void JSContext::checkImpl<JSObject*>(this=<unavailable>, argIndex=0) at JSContext-inl.h:186 [opt]
    frame #7: 0x0000000119eb4052 XUL`JS::ReadableStreamGetMode(JSContext*, JS::Handle<JSObject*>, JS::ReadableStreamMode*) [inlined] void JSContext::check<JSObject*>(this=<unavailable>) at JSContext-inl.h:194 [opt]
    frame #8: 0x0000000119eb4033 XUL`JS::ReadableStreamGetMode(JSContext*, JS::Handle<JSObject*>, JS::ReadableStreamMode*) [inlined] js::ReadableStream* APIUnwrapAndDowncast<js::ReadableStream>(cx=0x000000010c629000, obj=0x00000f1cf9046c68) at Stream.cpp:4496 [opt]
    frame #9: 0x0000000119eb4033 XUL`JS::ReadableStreamGetMode(cx=0x000000010c629000, streamObj=<unavailable>, mode=0x00007ffee6d79424) at Stream.cpp:4559 [opt]
    frame #10: 0x00000001172f74e3 XUL`mozilla::dom::FetchBody<mozilla::dom::Response>::SetBodyUsed(this=0x00000001283f40e0, aCx=0x000000010c629000, aRv=0x00007ffee6d79ab0) at Fetch.cpp:1072 [opt]
    frame #11: 0x0000000116feeb59 XUL`mozilla::dom::cache::TypeUtils::ToCacheResponse(this=0x000000011426bc90, aCx=0x000000010c629000, aOut=0x000000012838d4f0, aIn=<unavailable>, aStreamCleanupList=0x00007ffee6d79a40, aRv=0x00007ffee6d79ab0) at TypeUtils.cpp:225 [opt]
    frame #12: 0x0000000116fb23b8 XUL`mozilla::dom::cache::AutoChildOpArgs::Add(this=0x000000010921507c, aCx=0x000000010c629000, aRequest=0x00000001283ddcc0, aBodyAction=<unavailable>, aSchemeAction=TypeErrorOnInvalidScheme, aResponse=0x00000001283f40e0, aRv=0x00007ffee6d79ab0) at AutoUtils.cpp:306 [opt]
    frame #13: 0x0000000116fb6881 XUL`mozilla::dom::cache::Cache::Put(this=0x000000011426bc90, aCx=0x000000010c629000, aRequest=<unavailable>, aResponse=0x00000001283f40e0, aRv=0x00007ffee6d79ab0) at Cache.cpp:420 [opt]
    frame #14: 0x000000011665a993 XUL`mozilla::dom::Cache_Binding::put_promiseWrapper(JSContext*, JS::Handle<JSObject*>, mozilla::dom::cache::Cache*, JSJitMethodCallArgs const&) [inlined] mozilla::dom::Cache_Binding::put(cx=<unavailable>, self=0x000000011426bc90, args=0x00007ffee6d79ac0) at CacheBinding.cpp:915 [opt]
    frame #15: 0x000000011665a6cf XUL`mozilla::dom::Cache_Binding::put_promiseWrapper(cx=<unavailable>, obj=<unavailable>, self=0x000000011426bc90, args=<unavailable>) at CacheBinding.cpp:931 [opt]
    frame #16: 0x0000000116f863b5 XUL`bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(cx=0x000000010c629000, argc=<unavailable>, vp=<unavailable>) at BindingUtils.cpp:3144 [opt]
    frame #17: 0x0000000119b35ad9 XUL`CallJSNative(cx=0x000000010c629000, native=(XUL`bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(JSContext*, unsigned int, JS::Value*) at BindingUtils.cpp:3118), args=0x00007ffee6d79d98)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) at Interpreter.cpp:440 [opt]
    frame #18: 0x0000000119b35464 XUL`js::InternalCallOrConstruct(cx=0x000000010c629000, args=0x00007ffee6d79d98, construct=<unavailable>) at Interpreter.cpp:532 [opt]
    frame #19: 0x0000000119b3632d XUL`js::Call(cx=<unavailable>, fval=<unavailable>, thisv=<unavailable>, args=0x00007ffee6d79d98, rval=<unavailable>) at Interpreter.cpp:603 [opt]
    frame #20: 0x000000011a145971 XUL`js::ForwardingProxyHandler::call(this=<unavailable>, cx=0x000000010c629000, proxy=<unavailable>, args=0x00007ffee6d7a338) const at Wrapper.cpp:162 [opt]
    frame #21: 0x000000011a123762 XUL`js::CrossCompartmentWrapper::call(this=0x000000011e530f10, cx=0x000000010c629000, wrapper=<unavailable>, args=0x00007ffee6d7a338) const at CrossCompartmentWrapper.cpp:238 [opt]
    frame #22: 0x000000011a1379f1 XUL`js::Proxy::call(cx=0x000000010c629000, proxy=<unavailable>, args=0x00007ffee6d7a338) at Proxy.cpp:503 [opt]
    frame #23: 0x0000000119b3566d XUL`js::InternalCallOrConstruct(cx=0x000000010c629000, args=0x00007ffee6d7a338, construct=<unavailable>) at Interpreter.cpp:506 [opt]
    frame #24: 0x0000000119b2bb10 XUL`Interpret(JSContext*, js::RunState&) [inlined] js::CallFromStack(cx=<unavailable>) at Interpreter.cpp:591 [opt]
    frame #25: 0x0000000119b2bb08 XUL`Interpret(cx=<unavailable>, state=<unavailable>) at Interpreter.cpp:3056 [opt]
    frame #26: 0x0000000119b2359f XUL`js::RunScript(cx=0x000000010c629000, state=0x00007ffee6d7a660) at Interpreter.cpp:420 [opt]
    frame #27: 0x0000000119b353c9 XUL`js::InternalCallOrConstruct(cx=0x000000010c629000, args=0x00007ffee6d7a708, construct=<unavailable>) at Interpreter.cpp:560 [opt]
    frame #28: 0x0000000119b3632d XUL`js::Call(cx=<unavailable>, fval=<unavailable>, thisv=<unavailable>, args=0x00007ffee6d7a708, rval=<unavailable>) at Interpreter.cpp:603 [opt]
    frame #29: 0x000000011a145971 XUL`js::ForwardingProxyHandler::call(this=<unavailable>, cx=0x000000010c629000, proxy=<unavailable>, args=0x00007ffee6d7aa18) const at Wrapper.cpp:162 [opt]
    frame #30: 0x000000011a123762 XUL`js::CrossCompartmentWrapper::call(this=0x000000011e530f10, cx=0x000000010c629000, wrapper=<unavailable>, args=0x00007ffee6d7aa18) const at CrossCompartmentWrapper.cpp:238 [opt]
    frame #31: 0x000000011a1379f1 XUL`js::Proxy::call(cx=0x000000010c629000, proxy=<unavailable>, args=0x00007ffee6d7aa18) at Proxy.cpp:503 [opt]
    frame #32: 0x0000000119b3566d XUL`js::InternalCallOrConstruct(cx=0x000000010c629000, args=0x00007ffee6d7aa18, construct=<unavailable>) at Interpreter.cpp:506 [opt]
    frame #33: 0x0000000119b3632d XUL`js::Call(cx=<unavailable>, fval=<unavailable>, thisv=<unavailable>, args=0x00007ffee6d7aa18, rval=<unavailable>) at Interpreter.cpp:603 [opt]
    frame #34: 0x0000000119bc182b XUL`js::Call(cx=0x000000010c629000, fval=JS::HandleValue @ r12, thisv=JS::HandleValue @ r15, arg0=<unavailable>, rval=JS::MutableHandleValue @ r14) at Interpreter.h:98 [opt]
    frame #35: 0x0000000119bebf54 XUL`PromiseReactionJob(cx=<unavailable>, argc=<unavailable>, vp=<unavailable>) at Promise.cpp:1660 [opt]
    frame #36: 0x0000000119b35ad9 XUL`CallJSNative(cx=0x000000010c629000, native=(XUL`PromiseReactionJob(JSContext*, unsigned int, JS::Value*) at Promise.cpp:1576), args=0x00007ffee6d7acd8)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) at Interpreter.cpp:440 [opt]
    frame #37: 0x0000000119b35464 XUL`js::InternalCallOrConstruct(cx=0x000000010c629000, args=0x00007ffee6d7acd8, construct=<unavailable>) at Interpreter.cpp:532 [opt]
    frame #38: 0x0000000119b3632d XUL`js::Call(cx=<unavailable>, fval=<unavailable>, thisv=<unavailable>, args=0x00007ffee6d7acd8, rval=<unavailable>) at Interpreter.cpp:603 [opt]
    frame #39: 0x000000011a0cff0f XUL`JS::Call(cx=0x000000010c629000, thisv=<unavailable>, fval=<unavailable>, args=0x00007ffee6d7ae30, rval=JS::MutableHandleValue @ 0x00007ffee6d7acc0) at jsapi.cpp:2623 [opt]
    frame #40: 0x0000000116313239 XUL`mozilla::dom::PromiseJobCallback::Call(this=<unavailable>, cx=0x000000010c629000, aThisVal=Handle<JS::Value> @ r15, aRv=0x00007ffee6d7aec0) at PromiseBinding.cpp:26 [opt]
    frame #41: 0x00000001145d30a4 XUL`mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) [inlined] mozilla::dom::PromiseJobCallback::Call(this=0x0000000128340900, aExecutionReason=<unavailable>, aExceptionHandling=eReportExceptions, aRealm=<unavailable>) at PromiseBinding.h:91 [opt]
    frame #42: 0x00000001145d3048 XUL`mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) [inlined] mozilla::dom::PromiseJobCallback::Call(this=0x0000000128340900, aExecutionReason=<unavailable>) at PromiseBinding.h:104 [opt]
    frame #43: 0x00000001145d3021 XUL`mozilla::PromiseJobRunnable::Run(this=0x00000001283d97f0, aAso=0x00007ffee6d7b148) at CycleCollectedJSContext.cpp:235 [opt]
    frame #44: 0x00000001145bf116 XUL`mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint(this=0x0000000109538000, aForce=<unavailable>) at CycleCollectedJSContext.cpp:595 [opt]
    frame #45: 0x00000001145bfacd XUL`mozilla::CycleCollectedJSContext::AfterProcessTask(this=0x0000000109538000, aRecursionDepth=<unavailable>) at CycleCollectedJSContext.cpp:437 [opt]
    frame #46: 0x00000001152ffab8 XUL`XPCJSContext::AfterProcessTask(this=0x0000000109538000, aNewRecursionDepth=1) at XPCJSContext.cpp:1261 [opt]
    frame #47: 0x00000001146bf332 XUL`nsThread::ProcessNextEvent(this=0x000000010944fc40, aMayWait=<unavailable>, aResult=0x00007ffee6d7b6ef) at nsThread.cpp:1226 [opt]
    frame #48: 0x00000001146c2ab8 XUL`NS_ProcessNextEvent(aThread=<unavailable>, aMayWait=false) at nsThreadUtils.cpp:482 [opt]
    frame #49: 0x0000000114d9e06e XUL`mozilla::ipc::MessagePump::Run(this=0x0000000109403ec0, aDelegate=0x00007ffee6d7b968) at MessagePump.cpp:88 [opt]
    frame #50: 0x0000000114d3dd05 XUL`MessageLoop::Run() [inlined] MessageLoop::RunHandler(this=<unavailable>) at message_loop.cc:308 [opt]
    frame #51: 0x0000000114d3dd00 XUL`MessageLoop::Run(this=<unavailable>) at message_loop.cc:290 [opt]
    frame #52: 0x000000011813d4c9 XUL`nsBaseAppShell::Run(this=0x00000001095755e0) at nsBaseAppShell.cpp:137 [opt]
    frame #53: 0x00000001181b3c46 XUL`nsAppShell::Run(this=0x00000001095755e0) at nsAppShell.mm:702 [opt]
    frame #54: 0x0000000119a12635 XUL`XRE_RunAppShell() at nsEmbedFunctions.cpp:911 [opt]
    frame #55: 0x0000000114d9ea12 XUL`mozilla::ipc::MessagePumpForChildProcess::Run(this=0x0000000109403ec0, aDelegate=0x00007ffee6d7b968) at MessagePump.cpp:238 [opt]
    frame #56: 0x0000000114d3dd05 XUL`MessageLoop::Run() [inlined] MessageLoop::RunHandler(this=<unavailable>) at message_loop.cc:308 [opt]
    frame #57: 0x0000000114d3dd00 XUL`MessageLoop::Run(this=<unavailable>) at message_loop.cc:290 [opt]
    frame #58: 0x0000000119a12109 XUL`XRE_InitChildProcess(aArgc=<unavailable>, aArgv=<unavailable>, aChildData=<unavailable>) at nsEmbedFunctions.cpp:749 [opt]
    frame #59: 0x0000000108e83f07 plugin-container`main [inlined] content_process_main(bootstrap=0x000000010942a170, argc=<unavailable>, argv=0x00007ffee6d7bc30) at plugin-container.cpp:49 [opt]
    frame #60: 0x0000000108e83edb plugin-container`main(argc=<unavailable>, argv=0x00007ffee6d7bc30) at MozillaRuntimeMain.cpp:23 [opt]
    frame #61: 0x00007fff6934ded9 libdyld.dylib`start + 1

Andrea, could you take a look?

This call to JS::ReadableStreamGetMode needs to be in an AutoRealm, unless we're sure that aCx is already in the same compartment as stream.

Other calls to the functions in js/public/Stream.h should be reviewed too. They have the same contract: all arguments must be same-compartment. (This is the rule for the whole JS API, actually, although in other headers there are occasional exceptions.)

Flags: needinfo?(jorendorff) → needinfo?(amarchesini)
Flags: needinfo?(amarchesini)

Comment on attachment 9050280 [details]
Bug 1532553 - Use AutoRealm before calling JS::ReadableStreamGetMode(), r?jorendorff

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: none
  • 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?: all
  • If not all supported branches, which bug introduced the flaw?: Bug 1486698
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: Easy
  • How likely is this patch to cause regressions; how much testing does it need?: None, it checks that JSContext is called on the correct global.
Attachment #9050280 - Flags: sec-approval?

This is too late for the Firefox 66 release. I'm approving checkin for April 2, two weeks into the next cycle.

Whiteboard: [checkin on 4/2/2019]
Attachment #9050280 - Flags: sec-approval? → sec-approval+
Group: dom-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla67

(In reply to Al Billings [:abillings] from comment #8)

I'm approving checkin for April 2, two weeks into the next cycle.

Or not, I guess.

Flags: in-testsuite?
Whiteboard: [checkin on 4/2/2019]
Assignee: jorendorff → amarchesini

Also, this'll need a rebased patch for ESR60 uplift.

Flags: needinfo?(amarchesini)
Attached patch esr60Splinter Review
Flags: needinfo?(amarchesini)
Flags: qe-verify+
Whiteboard: [post-critsmash-triage]

I managed to reproduce this issue on Firefox 67.0a1 (2019-03-05) ASAN build, under Windows 10x64.
I can confirm that the issue is not reproducible on Firefox 67.0b8, under Windows 10x64, but I was not able to find the latest Beta ASAN build (67.0b8) for Windows in Taskcluster or Treeherder.
Nils, can you please provide me a link from the latest Beta ASAN build (67.0b8) if available?

Note that I was not able to reproduce the issue on Ubuntu 18.04x64, by using an affected build 67.0a1 ASAN (2019-03-05), or latest Beta ASAN build (67.0b8).

Since I was not able to confirm the issue on Firefox 67.0b8 ASAN build, I am not marking this issue as Verified.
I will follow up as soon as I will be able to confirm the issue on the build mentioned above.

Flags: needinfo?(nils)

Comment on attachment 9050280 [details]
Bug 1532553 - Use AutoRealm before calling JS::ReadableStreamGetMode(), r?jorendorff

Beta/Release Uplift Approval Request

  • Feature/Bug causing the regression: Bug 1486698
  • User impact if declined: A crash can occur.
  • Is this code covered by automated tests?: No
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: Yes
  • If yes, steps to reproduce: There is a test on the bug to reproduce this issue.
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The fix is about use the right JS compartments in the fetch API code when where are ReadableStreams involved.
    It was been in nightly for a while. Low risk.
  • String changes made/needed: none
Attachment #9050280 - Flags: approval-mozilla-beta?
Attachment #9051454 - Flags: approval-mozilla-beta?
Flags: qe-verify+ → qe-verify?

Comment on attachment 9050280 [details]
Bug 1532553 - Use AutoRealm before calling JS::ReadableStreamGetMode(), r?jorendorff

This landed while 67 was on Nightly, so there's no need to uplift it to Beta.

Attachment #9050280 - Flags: approval-mozilla-beta?
Attachment #9051454 - Flags: approval-mozilla-beta? → approval-mozilla-esr60?
QA Whiteboard: [qa-triaged]
Flags: qe-verify? → qe-verify+

I managed to verify the issue on Firefox 67.0b10 and on Firefox ASAN 68.0a1 (2019-04-12), under Windows 10x64.
Based on this and on Comment 13, I am marking this issue as Verified Fixed.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
Comment on attachment 9051454 [details] [diff] [review]
esr60

Fix for sec-high issue, verified in nightly.
OK for uplift for 60.7.0 esr.
Attachment #9051454 - Flags: approval-mozilla-esr60? → approval-mozilla-esr60+
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main67+][adv-esr60.7+]
Alias: CVE-2019-9819
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Keywords: regression
Regressed by: 1486698
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.