Closed Bug 1460619 Opened 7 years ago Closed 7 years ago

AddressSanitizer: heap-use-after-free [@ Length] with READ of size 8

Categories

(Core :: WebVR, defect)

59 Branch
defect
Not set
critical

Tracking

()

RESOLVED FIXED
mozilla66
Tracking Status
firefox-esr60 65+ fixed
firefox64 --- wontfix
firefox65 + fixed
firefox66 + fixed

People

(Reporter: jkratzer, Assigned: kip)

References

(Blocks 2 open bugs)

Details

(4 keywords, Whiteboard: [adv-main65+][adv-esr60.5+])

Attachments

(5 files)

Found while fuzzing mozilla-central rev 96b37ba12225. I'm currently reducing the testcase and will update once complete. ==17210==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000239568 at pc 0x7f7456cd12e3 bp 0x7ffc3d2d2870 sp 0x7ffc3d2d2868 READ of size 8 at 0x604000239568 thread T0 (file:// Content) #0 0x7f7456cd12e2 in Length /builds/worker/workspace/build/src/obj-firefox/dist/include/nsTArray.h:369:37 #1 0x7f7456cd12e2 in AppendElement<RefPtr<mozilla::gfx::VRLayerChild> &, nsTArrayInfallibleAllocator> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsTArray.h:2287 #2 0x7f7456cd12e2 in mozilla::gfx::VRDisplayPresentation::CreateLayers() /builds/worker/workspace/build/src/gfx/vr/VRDisplayPresentation.cpp:106 #3 0x7f745b7dfe9f in mozilla::dom::VRDisplay::RequestPresent(nsTArray<mozilla::dom::VRLayer> const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/vr/VRDisplay.cpp:569:22 #4 0x7f74589368bf in requestPresent /builds/worker/workspace/build/src/obj-firefox/dom/bindings/VRDisplayBinding.cpp:1095:45 #5 0x7f74589368bf in mozilla::dom::VRDisplayBinding::requestPresent_promiseWrapper(JSContext*, JS::Handle<JSObject*>, mozilla::dom::VRDisplay*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/VRDisplayBinding.cpp:1109 #6 0x7f74598144e3 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:3260:13 #7 0x7f74600be027 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15 #8 0x7f74600be027 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467 #9 0x7f74600a8820 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:522:12 #10 0x7f74600a8820 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086 #11 0x7f746008efe3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:417:12 #12 0x7f74600bdda5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:489:15 #13 0x7f74600bf022 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:535:10 #14 0x7f746021e68e in PromiseReactionJob(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/builtin/Promise.cpp:1237:14 #15 0x7f74600be027 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15 #16 0x7f74600be027 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467 #17 0x7f74600bf022 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:535:10 #18 0x7f7460bf6f6a 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:2989:12 #19 0x7f7457f08162 in mozilla::dom::PromiseJobCallback::Call(JSContext*, JS::Handle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/PromiseBinding.cpp:25:8 #20 0x7f7454031735 in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:91:12 #21 0x7f7454031735 in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:104 #22 0x7f7454031735 in mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:205 #23 0x7f7454015041 in mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint() /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:543:17 #24 0x7f7459f45e3a in LeaveMicroTask /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/CycleCollectedJSContext.h:200:7 #25 0x7f7459f45e3a in ~nsAutoMicroTask /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/CycleCollectedJSContext.h:295 #26 0x7f7459f45e3a in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1123 #27 0x7f7459f4738b in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1288:20 #28 0x7f7459f31737 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16 #29 0x7f7459f35533 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:961:9 #30 0x7f7459f37a6b in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp #31 0x7f7457479a28 in nsINode::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1079:5 #32 0x7f7456fc4a13 in nsContentUtils::DispatchEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool, bool*, bool) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4474:28 #33 0x7f7456fc47f4 in nsContentUtils::DispatchTrustedEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4442:10 #34 0x7f74573ab524 in nsIDocument::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5208:3 #35 0x7f74574beda4 in applyImpl<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1165:12 #36 0x7f74574beda4 in apply<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1171 #37 0x7f74574beda4 in mozilla::detail::RunnableMethodImpl<nsIDocument*, void (nsIDocument::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1216 #38 0x7f745419a2a1 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:337:32 #39 0x7f74541b8f63 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1090:14 #40 0x7f74541d4b30 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:519:10 #41 0x7f74550b365a in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/workspace/build/src/ipc/glue/MessagePump.cpp:97:21 #42 0x7f7455007649 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10 #43 0x7f7455007649 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319 #44 0x7f7455007649 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299 #45 0x7f745bb7aefa in nsBaseAppShell::Run() /builds/worker/workspace/build/src/widget/nsBaseAppShell.cpp:157:27 #46 0x7f745fdd532b in XRE_RunAppShell() /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:893:22 #47 0x7f7455007649 in RunInternal /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:326:10 #48 0x7f7455007649 in RunHandler /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:319 #49 0x7f7455007649 in MessageLoop::Run() /builds/worker/workspace/build/src/ipc/chromium/src/base/message_loop.cc:299 #50 0x7f745fdd4cf0 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/workspace/build/src/toolkit/xre/nsEmbedFunctions.cpp:719:34 #51 0x4f50dc in content_process_main /builds/worker/workspace/build/src/browser/app/../../ipc/contentproc/plugin-container.cpp:50:30 #52 0x4f50dc in main /builds/worker/workspace/build/src/browser/app/nsBrowserApp.cpp:282 #53 0x7f7473e4182f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291 #54 0x42476c in _start (/home/forb1dden/builds/mc-asan/firefox+0x42476c) 0x604000239568 is located 24 bytes inside of 40-byte region [0x604000239550,0x604000239578) freed by thread T0 (file:// Content) here: #0 0x4c5172 in __interceptor_free /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:68:3 #1 0x7f745b7e051c in operator delete /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:180:12 #2 0x7f745b7e051c in Release /builds/worker/workspace/build/src/obj-firefox/dist/include/VRDisplayPresentation.h:20 #3 0x7f745b7e051c in Release /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:41 #4 0x7f745b7e051c in Release /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:398 #5 0x7f745b7e051c in assign_assuming_AddRef /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:66 #6 0x7f745b7e051c in operator= /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/RefPtr.h:168 #7 0x7f745b7e051c in ExitPresentInternal /builds/worker/workspace/build/src/dom/vr/VRDisplay.cpp:632 #8 0x7f745b7e051c in Shutdown /builds/worker/workspace/build/src/dom/vr/VRDisplay.cpp:639 #9 0x7f745b7e051c in mozilla::dom::VRDisplay::Observe(nsISupports*, char const*, char16_t const*) /builds/worker/workspace/build/src/dom/vr/VRDisplay.cpp:594 #10 0x7f74540b54c3 in nsObserverList::NotifyObservers(nsISupports*, char const*, char16_t const*) /builds/worker/workspace/build/src/xpcom/ds/nsObserverList.cpp:112:19 #11 0x7f74540b8ddb in nsObserverService::NotifyObservers(nsISupports*, char const*, char16_t const*) /builds/worker/workspace/build/src/xpcom/ds/nsObserverService.cpp:297:19 #12 0x7f74572c2ad2 in mozilla::WindowDestroyedEvent::Run() /builds/worker/workspace/build/src/dom/base/WindowDestroyedEvent.cpp:62:22 #13 0x7f745419a2a1 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:337:32 #14 0x7f74541b8f63 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1090:14 #15 0x7f74541d4b30 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/workspace/build/src/xpcom/threads/nsThreadUtils.cpp:519:10 #16 0x7f745b39eebc in SpinEventLoopUntil<mozilla::ProcessFailureBehavior::ReportToCaller, (lambda at /builds/worker/workspace/build/src/dom/ipc/ContentChild.cpp:1137:24)> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:324:25 #17 0x7f745b39eebc in mozilla::dom::ContentChild::ProvideWindowCommon(mozilla::dom::TabChild*, mozIDOMWindowProxy*, bool, unsigned int, bool, bool, bool, nsIURI*, nsTSubstring<char16_t> const&, nsTSubstring<char> const&, bool, nsIDocShellLoadInfo*, bool*, mozIDOMWindowProxy**) /builds/worker/workspace/build/src/dom/ipc/ContentChild.cpp:1137 #18 0x7f745b427a0c in mozilla::dom::TabChild::ProvideWindow(mozIDOMWindowProxy*, unsigned int, bool, bool, bool, nsIURI*, nsTSubstring<char16_t> const&, nsTSubstring<char> const&, bool, nsIDocShellLoadInfo*, bool*, mozIDOMWindowProxy**) /builds/worker/workspace/build/src/dom/ipc/TabChild.cpp:1040:16 #19 0x7f745fd359fa in nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy*, char const*, char const*, char const*, bool, bool, bool, nsIArray*, bool, bool, nsIDocShellLoadInfo*, mozIDOMWindowProxy**) /builds/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp:825:24 #20 0x7f745fd3b385 in OpenWindow2 /builds/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp:417:10 #21 0x7f745fd3b385 in non-virtual thunk to nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy*, char const*, char const*, char const*, bool, bool, bool, nsISupports*, bool, bool, nsIDocShellLoadInfo*, mozIDOMWindowProxy**) /builds/worker/workspace/build/src/toolkit/components/windowwatcher/nsWindowWatcher.cpp #22 0x7f74570e3deb in nsGlobalWindowOuter::OpenInternal(nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, bool, bool, bool, bool, bool, nsIArray*, nsISupports*, nsIDocShellLoadInfo*, bool, nsPIDOMWindowOuter**) /builds/worker/workspace/build/src/dom/base/nsGlobalWindowOuter.cpp:7026:21 #23 0x7f74570e2c3a in OpenJS /builds/worker/workspace/build/src/dom/base/nsGlobalWindowOuter.cpp:5503:10 #24 0x7f74570e2c3a in nsGlobalWindowOuter::OpenOuter(nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsGlobalWindowOuter.cpp:5478 #25 0x7f7458bfb9b2 in mozilla::dom::WindowBinding::open(JSContext*, JS::Handle<JSObject*>, nsGlobalWindowInner*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/WindowBinding.cpp:2294:56 #26 0x7f7459815013 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::MaybeGlobalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/dom/bindings/BindingUtils.cpp:3260:13 #27 0x7f74600be027 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15 #28 0x7f74600be027 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467 #29 0x7f74600a8820 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:522:12 #30 0x7f74600a8820 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086 #31 0x7f746008efe3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:417:12 #32 0x7f74600bdda5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:489:15 #33 0x7f74600bf022 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:535:10 #34 0x7f7460bf6f6a 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:2989:12 #35 0x7f7459159b7d in mozilla::dom::Function::Call(JSContext*, JS::Handle<JS::Value>, nsTArray<JS::Value> const&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/FunctionBinding.cpp:40:8 #36 0x7f745709a9ab in Call<nsCOMPtr<nsISupports> > /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/FunctionBinding.h:73:12 #37 0x7f745709a9ab in nsGlobalWindowInner::RunTimeoutHandler(mozilla::dom::Timeout*, nsIScriptContext*) /builds/worker/workspace/build/src/dom/base/nsGlobalWindowInner.cpp:6657 #38 0x7f74572b3976 in mozilla::dom::TimeoutManager::RunTimeout(mozilla::TimeStamp const&, mozilla::TimeStamp const&) /builds/worker/workspace/build/src/dom/base/TimeoutManager.cpp:877:42 #39 0x7f74572b2c54 in mozilla::dom::TimeoutExecutor::MaybeExecute() /builds/worker/workspace/build/src/dom/base/TimeoutExecutor.cpp:172:11 #40 0x7f74572b4e56 in Notify /builds/worker/workspace/build/src/dom/base/TimeoutExecutor.cpp:240:5 #41 0x7f74572b4e56 in non-virtual thunk to mozilla::dom::TimeoutExecutor::Notify(nsITimer*) /builds/worker/workspace/build/src/dom/base/TimeoutExecutor.cpp #42 0x7f74541d9a5b in nsTimerImpl::Fire(int) /builds/worker/workspace/build/src/xpcom/threads/nsTimerImpl.cpp:704:40 #43 0x7f74541a9089 in nsTimerEvent::Run() /builds/worker/workspace/build/src/xpcom/threads/TimerThread.cpp:290:11 #44 0x7f74541c5947 in mozilla::ThrottledEventQueue::Inner::ExecuteRunnable() /builds/worker/workspace/build/src/xpcom/threads/ThrottledEventQueue.cpp:188:22 previously allocated by thread T0 (file:// Content) here: #0 0x4c54b3 in malloc /builds/worker/workspace/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88:3 #1 0x4f5f7d in moz_xmalloc /builds/worker/workspace/build/src/memory/mozalloc/mozalloc.cpp:70:17 #2 0x7f7456ccee4f in operator new /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/mozalloc.h:156:12 #3 0x7f7456ccee4f in mozilla::gfx::VRDisplayClient::BeginPresentation(nsTArray<mozilla::dom::VRLayer> const&, unsigned int) /builds/worker/workspace/build/src/gfx/vr/VRDisplayClient.cpp:57 #4 0x7f745b7e0010 in mozilla::dom::VRDisplay::RequestPresent(nsTArray<mozilla::dom::VRLayer> const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/vr/VRDisplay.cpp:571:32 #5 0x7f74589368bf in requestPresent /builds/worker/workspace/build/src/obj-firefox/dom/bindings/VRDisplayBinding.cpp:1095:45 #6 0x7f74589368bf in mozilla::dom::VRDisplayBinding::requestPresent_promiseWrapper(JSContext*, JS::Handle<JSObject*>, mozilla::dom::VRDisplay*, JSJitMethodCallArgs const&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/VRDisplayBinding.cpp:1109 #7 0x7f74598144e3 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:3260:13 #8 0x7f74600be027 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15 #9 0x7f74600be027 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467 #10 0x7f74600a8820 in CallFromStack /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:522:12 #11 0x7f74600a8820 in Interpret(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:3086 #12 0x7f746008efe3 in js::RunScript(JSContext*, js::RunState&) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:417:12 #13 0x7f74600bdda5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:489:15 #14 0x7f74600bf022 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:535:10 #15 0x7f746021e68e in PromiseReactionJob(JSContext*, unsigned int, JS::Value*) /builds/worker/workspace/build/src/js/src/builtin/Promise.cpp:1237:14 #16 0x7f74600be027 in CallJSNative /builds/worker/workspace/build/src/js/src/vm/JSContext-inl.h:280:15 #17 0x7f74600be027 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) /builds/worker/workspace/build/src/js/src/vm/Interpreter.cpp:467 #18 0x7f74600bf022 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:535:10 #19 0x7f7460bf6f6a 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:2989:12 #20 0x7f7457f08162 in mozilla::dom::PromiseJobCallback::Call(JSContext*, JS::Handle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/build/src/obj-firefox/dom/bindings/PromiseBinding.cpp:25:8 #21 0x7f7454031735 in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:91:12 #22 0x7f7454031735 in Call /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/dom/PromiseBinding.h:104 #23 0x7f7454031735 in mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:205 #24 0x7f7454015041 in mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint() /builds/worker/workspace/build/src/xpcom/base/CycleCollectedJSContext.cpp:543:17 #25 0x7f7459f45e3a in LeaveMicroTask /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/CycleCollectedJSContext.h:200:7 #26 0x7f7459f45e3a in ~nsAutoMicroTask /builds/worker/workspace/build/src/obj-firefox/dist/include/mozilla/CycleCollectedJSContext.h:295 #27 0x7f7459f45e3a in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1123 #28 0x7f7459f4738b in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventListenerManager.cpp:1288:20 #29 0x7f7459f31737 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:528:16 #30 0x7f7459f35533 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp:961:9 #31 0x7f7459f37a6b in mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/workspace/build/src/dom/events/EventDispatcher.cpp #32 0x7f7457479a28 in nsINode::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/workspace/build/src/dom/base/nsINode.cpp:1079:5 #33 0x7f7456fc4a13 in nsContentUtils::DispatchEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool, bool*, bool) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4474:28 #34 0x7f7456fc47f4 in nsContentUtils::DispatchTrustedEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool*) /builds/worker/workspace/build/src/dom/base/nsContentUtils.cpp:4442:10 #35 0x7f74573ab524 in nsIDocument::DispatchContentLoadedEvents() /builds/worker/workspace/build/src/dom/base/nsDocument.cpp:5208:3 #36 0x7f74574beda4 in applyImpl<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1165:12 #37 0x7f74574beda4 in apply<nsIDocument, void (nsIDocument::*)()> /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1171 #38 0x7f74574beda4 in mozilla::detail::RunnableMethodImpl<nsIDocument*, void (nsIDocument::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/build/src/obj-firefox/dist/include/nsThreadUtils.h:1216 #39 0x7f745419a2a1 in mozilla::SchedulerGroup::Runnable::Run() /builds/worker/workspace/build/src/xpcom/threads/SchedulerGroup.cpp:337:32 #40 0x7f74541b8f63 in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/workspace/build/src/xpcom/threads/nsThread.cpp:1090:14 SUMMARY: AddressSanitizer: heap-use-after-free /builds/worker/workspace/build/src/obj-firefox/dist/include/nsTArray.h:369:37 in Length Shadow bytes around the buggy address: 0x0c088003f250: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f260: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f270: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f280: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f290: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa =>0x0c088003f2a0: fa fa fd fd fd fd fd fd fa fa fd fd fd[fd]fd fa 0x0c088003f2b0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f2c0: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 fa 0x0c088003f2d0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f2e0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x0c088003f2f0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==17210==ABORTING
Group: core-security → gfx-core-security
Flags: needinfo?(kgilbert)
Attached file harness.html
Attached file trigger.html
The attached file will trigger the issue however, harness.html must be called as the entry-point URL.
Attached file prefs.js
Required prefs.
Assignee: nobody → kgilbert
Flags: needinfo?(kgilbert)
Core of this appears to be that the VRDisplayPresentation is destroyed during the time between the VRDisplay.requestPresent() call and its returned promise. Although the VRDisplay was kept alive, the VRDisplay::mPresentation was cleared.
On closer inspection, VRDisplay::RequestPresent has a check for VRDisplay::mPresentation being allocated. Perhaps the entire VRdisplay was destroyed between the navigator.getVRDisplays() call and it's returned promise being resolved.
Kip, are you going to be able to look at this again? The bug is a sec-high and about 6 months old. Thanks.
Flags: needinfo?(kgilbert)
Just back from PTO. I'll be spending some time on this issue and hopefully have a resolution quickly.
Flags: needinfo?(kgilbert)
Have not been able to repro in Windows yet. I'll try some tests with Linux/ASAN builds tomorrow.
I have managed to repro in Linux with an ASAN build. WIP on a fix now.
I have just found the issue... This was regressed by Bug 1394600 (Allow VRDisplay.requestPresent update the VR layers after presentation has already begun) Bug 1394600 updated VRLayerChild::Initialize to allow it to both initialize and update VRLayerChild's eye rectangles and canvas element: ---------- void -VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement) +VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement, + const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) { MOZ_ASSERT(aCanvasElement); - mCanvasElement = aCanvasElement; - mCanvasElement->StartVRPresentation(); - - VRManagerChild *vrmc = VRManagerChild::Get(); - vrmc->RunFrameRequestCallbacks(); + aCanvasElement->StartVRPresentation(); + mLeftEyeRect = aLeftEyeRect; + mRightEyeRect = aRightEyeRect; + if (mCanvasElement == nullptr) { + mCanvasElement = aCanvasElement; + VRManagerChild *vrmc = VRManagerChild::Get(); + vrmc->RunFrameRequestCallbacks(); + } else { + mCanvasElement = aCanvasElement; + } } ---------- The line in particular that introduced this bug: vrmc->RunFrameRequestCallbacks(); This call allowed JS to run after the check for VRDisplay::mPresentation, but still before the derefrencing of the VRDisplayPresentation members included in the UAF call stack. By adding some debugging mutex' to the code, I was able to cause a deadlock that identifies the particular call-stack including this particular chain of events leading up to the UAF. I have attached this particular call stack for reference. I suspect that we can simply remove the call to vrmc->RunFrameRequestCallbacks() in VRLayerChild::Initialize. I will first check if this results in any regressions for the WebVR test pages at http://webvr.info/samples/
It is possible that this bug could be the cause for other crashes with other call stack variations, depending on the unique Javascript calls made in the Navigator.GetVRDisplays() promise callback.
I have tested this patch locally and verified that this doesn't regress the "Dynamic Canvas Size" test page that changes the layers mid-presentation: https://webvr.info/samples/test-slow-render.html?standardSize=1&renderScale=1.0&canvasResizeInterval=33
The call to VRManagerChild::RunFrameRequestCallbacks() does not appear to be necessary after initializing a VR Layer any more, as we have added a different mechanism to keep the RAF cycles pumping since this code was originally landed.
Attachment #9034034 - Flags: review?(continuation)
Comment on attachment 9034034 [details] [diff] [review] Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers Review of attachment 9034034 [details] [diff] [review]: ----------------------------------------------------------------- Sorry, I don't know anything about this code.
Attachment #9034034 - Flags: review?(continuation)
This patch will also fix Bug 1496842
Blocks: 1496842
Attachment #9034034 - Flags: review?(dmu)
Comment on attachment 9034034 [details] [diff] [review] Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers Review of attachment 9034034 [details] [diff] [review]: ----------------------------------------------------------------- LGTM!
Attachment #9034034 - Flags: review?(dmu) → review+
Blocks: 1515938
Comment on attachment 9034034 [details] [diff] [review] Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers [Security Approval Request] How easily could an exploit be constructed based on the patch?: The patch does not directly point to a means of exploit. Even with the call stack from the repro, it would be very difficult to reproduce the precise timing needed to hit this condition without using the "Puppet VR" test interface used by the fuzzer. The "Puppet VR" test interface is not enabled by default (via a pref) and only used by tests. 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?: beta, release If not all supported branches, which bug introduced the flaw?: Bug 1394600 Do you have backports for the affected branches?: No If not, how different, hard to create, and risky will they be?: Easy to create for Beta, potentially risky for Release. The patch simply deletes two lines of code. This same patch could be applied to Beta after simply rebasing. If rebased to Release, there are potentially regressions to WebVR functionality (eg, incorrect rendering resolution or RAF loop freezing in the headset) How likely is this patch to cause regressions; how much testing does it need?: This affects a rarely used feature (updating the VR layers during a running VR presentation without restarting it). Manual testing shows that it does not regress the sample pages on https://webvr.info/samples that exercise this feature. If any regressions occur, they would only affect WebVR content using this feature.
Attachment #9034034 - Flags: sec-approval?
Comment on attachment 9034034 [details] [diff] [review] Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers sec-approval+ for trunk. I'd like to get a beta patch for this nominated as well. Normally I'd want an ESR patch but I'm not sure if VR is enough of a feature, especially since the issue is mostly hidden behind a pref, for this to matter on ESR.
Attachment #9034034 - Flags: sec-approval? → sec-approval+

Comment on attachment 9034034 [details] [diff] [review]
Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers

[Beta/Release Uplift Approval Request]

Feature/Bug causing the regression: Bug 1394600

User impact if declined: A crash due to UAF may occur of a GC event occurs with precise timing on a computer with VR hardware attached while visiting a WebVR patch.

Is this code covered by automated tests?: Yes

Has the fix been verified in Nightly?: Yes

Needs manual test from QE?: No

If yes, steps to reproduce:

List of other uplifts needed: None

Risk to taking this patch: Low

Why is the change risky/not risky? (and alternatives if risky): This affects a rarely used feature (updating the VR layers during a running VR presentation without restarting it). Manual testing shows that it does not regress the sample pages on https://webvr.info/samples that exercise this feature. If any regressions occur, they would only affect WebVR content using this feature.

String changes made/needed: None

Attachment #9034034 - Flags: approval-mozilla-beta?
Group: gfx-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla66

Comment on attachment 9034034 [details] [diff] [review]
Bug 1460619 - Do not run frame request callbacks immediately after updating VR layers

[Triage Comment]
Fixes a WebVR sec issue. Approved for 65.0b10 and 60.5.0esr.

Attachment #9034034 - Flags: approval-mozilla-esr60+
Attachment #9034034 - Flags: approval-mozilla-beta?
Attachment #9034034 - Flags: approval-mozilla-beta+
Flags: qe-verify-
Whiteboard: [adv-main65+][adv-esr60.5+]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: