JS engine crashes with heap-spray testcase




JavaScript Engine
8 years ago
26 days ago


(Reporter: Benjamin Smedberg, Assigned: Robert Sayre)



Mac OS X

Firefox Tracking Flags

(blocking2.0 -, status1.9.2 wanted, status1.9.1 ?)


(Whiteboard: [sg:needinfo][critsmash:investigating][stale][needs Purify][softblocker])



8 years ago
mozilla-central today's nightly, Windows, OOPP turned off: the test case from bug 532246 is causing crashes, apparently in the JS engine, and apparently not related to the original cause of the testcase (which was independent plugins scripting eachother). The testcase performs a heap spray using Java.

one crash:

     mozcrt19.dll!free(void * ptr=0x07e0a800)  Line 6017 + 0x16 bytes    C
>	mozjs.dll!js::TraceRecorder::~TraceRecorder()  Line 2334 + 0x1e bytes	C++
     mozjs.dll!js::TraceRecorder::finishAbort(const char * reason=0x72146414) 
Line 2417 + 0xd bytes    C++
     mozjs.dll!js::AbortRecordingImpl(JSContext * cx=)  Line 7157    C++
     mozjs.dll!js::ResetJITImpl(JSContext * cx=0x00000000)  + 0x8f0b6 bytes   


mozjs.dll!js::TraceRecorder::checkForGlobalObjectReallocation()  Line 3696 +
0x10 bytes    C++
     mozjs.dll!js::TraceRecorder::snapshot(js::ExitType exitType=TIMEOUT_EXIT) 
Line 3968 + 0x5 bytes    C++
     mozjs.dll!js::TraceRecorder::TraceRecorder(JSContext * cx=0x06563400,
js::VMSideExit * anchor=0x00000000, js::VMFragment * fragment=0x062032e0,
unsigned int stackSlots=0x0000000e, unsigned int ngslots=0x00000000,
js::TraceType_ * typeMap=0x062033a0, js::VMSideExit * innermost=0x00000000,
unsigned char * outer=0x00000000, unsigned long outerArgc=0x00000000,
js::RecordReason recordReason=Record_Branch)  Line 2307 + 0x2b bytes    C++
     mozjs.dll!js::RecordTree(JSContext * cx=0x00000000, js::TreeFragment *
peer=0x00000000, unsigned char * outer=0x00000000, unsigned long
outerArgc=0x00000000, js::Queue<unsigned short> * globalSlots=0x0070e028,
js::RecordReason reason=Record_Branch)  Line 5653 + 0x5e bytes    C++
     mozjs.dll!js::MonitorLoopEdge(JSContext * cx=0x06563400, unsigned int &
inlineCallCount=0x00000000, js::RecordReason reason=Record_Branch)  Line 6937 +
0x21 bytes    C++
     mozjs.dll!js_Interpret(JSContext * cx=)  Line 911 + 0xc7 bytes    C++
     mozjs.dll!js_Invoke(JSContext * cx=0x06563400, unsigned int
argc=0x00000004, int * vp=0x0654d048, unsigned int flags=0x00000000)  Line 843
+ 0x6 bytes    C++
     xul.dll!nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS *
wrapper=0x061a1700, unsigned short methodIndex=0x0003, const
XPTMethodDescriptor * info=0x03be8e20, nsXPTCMiniVariant *
nativeParams=0x0039c9b4)  Line 1697    C++
     xul.dll!nsXPCWrappedJS::CallMethod(unsigned short methodIndex=0x0003,
const XPTMethodDescriptor * info=0x03be8e20, nsXPTCMiniVariant *
params=0x0039c9b4)  Line 571    C++
     xul.dll!PrepareAndDispatch(nsXPTCStubBase * self=0x0614da70, unsigned int
methodIndex=0x00000003, unsigned int * args=0x0039ca6c, unsigned int *
stackBytesToPop=0x0039ca5c)  Line 114 + 0x15 bytes    C++
     xul.dll!SharedStub()  Line 142    C++
     xul.dll!nsBrowserStatusFilter::OnStateChange(nsIWebProgress *
aWebProgress=0x03b67024, nsIRequest * aRequest=0x62ecbeac, unsigned int
aStateFlags=0x000f0001, unsigned int aStatus=0x00000000)  Line 183 + 0x13 bytes
     xul.dll!nsDocLoader::FireOnStateChange(nsIWebProgress *
aProgress=0x03b67024, nsIRequest * aRequest=0x62ecbeac, int
aStateFlags=0x000f0001, unsigned int aStatus=0x00000000)  Line 1314 + 0x1c
bytes    C++
     xul.dll!nsDocLoader::OnStartRequest(nsIRequest * request=0x62ecbeac,
nsISupports * aCtxt=0x00000000)  Line 555 + 0x1c bytes    C++
     xul.dll!nsLoadGroup::AddRequest(nsIRequest * request=0x03b67014,
nsISupports * ctxt=0x00000000)  Line 596    C++
     xul.dll!nsBaseChannel::AsyncOpen(nsIStreamListener * listener=0x07144a00,
nsISupports * ctxt=0x00000000)  Line 564    C++
     xul.dll!nsURILoader::OpenURI(nsIChannel * channel=0x07144a00, int
aIsContentPreferred=0x00000000, nsIInterfaceRequestor *
aWindowContext=0x03b67028)  Line 843    C++
     xul.dll!nsDocShell::DoChannelLoad(nsIChannel * aChannel=0x62ecbeac,
nsIURILoader * aURILoader=0x0426a9c0, int aBypassClassifier=0x00000000)  Line
8641    C++
     xul.dll!nsDocShell::DoURILoad(nsIURI * aURI=0x05b79ab0, nsIURI *
aReferrerURI=0x00000000, int aSendReferrer=0x00000001, nsISupports *
aOwner=0x00000000, const char * aTypeHint=0x6ea80e80, nsIInputStream *
aPostData=0x00000000, nsIInputStream * aHeadersData=0x00000000, int
aFirstParty=0x00000001, nsIDocShell * * aDocShell=0x00000000, nsIRequest * *
aRequest=0x0039cc68, int aIsNewWindowTarget=0x00000000, int
aBypassClassifier=0x00000000, int aForceAllowCookies=0x00000000)  Line 8492   
     xul.dll!nsDocShell::InternalLoad(nsIURI * aURI=0x05b79ab0, nsIURI *
aReferrer=0x00000000, nsISupports * aOwner=0x00000000, unsigned int
aFlags=0x00000000, const wchar_t * aWindowTarget=0x00000000, const char *
aTypeHint=0x6ea80e80, nsIInputStream * aPostData=0x00000000, nsIInputStream *
aHeadersData=0x00000000, unsigned int aLoadType=0x00000002, nsISHEntry *
aSHEntry=0x05b79a00, int aFirstParty=0x00000001, nsIDocShell * *
aDocShell=0x00000000, nsIRequest * * aRequest=0x00000000)  Line 8176 + 0x6e
bytes    C++
     xul.dll!nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry=0x00000000,
unsigned int aLoadType=0x00000000)  Line 9654    C++
     xul.dll!nsCOMPtr_base::assign_from_qi(nsQueryInterface qi={...}, const
nsID & iid={...})  Line 99    C++
     xul.dll!XPCCallContext::~XPCCallContext()  Line 428 + 0xa bytes    C++
     xul.dll!XPC_WN_OnlyIWrite_Proto_PropertyStub(JSContext * cx=0x03b67010,
JSObject * obj=0x6e0aec2b, int idval=0x6e910910, int * vp=0x0039cf70)  Line
2026 + 0x9 bytes    C++
     xul.dll!nsCOMPtr_base::~nsCOMPtr_base()  Line 82    C++
     xul.dll!nsQueryReferent::operator()(const nsID & aIID={...}, void * *
answer=0x0039cf48)  Line 88 + 0x2e bytes    C++
     xul.dll!nsCOMPtr_base::assign_from_helper(const nsCOMPtr_helper &
helper={...}, const nsID & iid={...})  Line 150 + 0x11 bytes    C++
nsCOMPtr_helper & helper={...})  Line 623    C++
     xul.dll!nsLocation::Reload(int aForceget=0x00000000)  Line 813    C++
     xul.dll!NS_InvokeByIndex_P(nsISupports * that=0x05bb6ea0, unsigned int
methodIndex=0x00000013, unsigned int paramCount=0x00000001, nsXPTCVariant *
params=0x0039d038)  Line 103    C++
     xul.dll!XPCWrappedNative::CallMethod(XPCCallContext & ccx={...},
XPCWrappedNative::CallMode mode=CALL_METHOD)  Line 2750 + 0x1e bytes    C++
     xul.dll!XPC_WN_CallMethod(JSContext * cx=0x06563400, JSObject *
obj=0x0330e680, unsigned int argc=0x00000000, int * argv=0x0654d034, int *
vp=0x0039d370)  Line 1770 + 0x12 bytes    C++
     mozjs.dll!js_Invoke(JSContext * cx=, unsigned int argc=, int * vp=,
unsigned int flags=)  Line 835 + 0x15 bytes    C++
     mozjs.dll!js_Interpret(JSContext * cx=0x06563400)  Line 2271    C++
     mozjs.dll!js_Invoke(JSContext * cx=0x06563400, unsigned int
argc=0x00000001, int * vp=0x0654d020, unsigned int flags=0x00000000)  Line 843
+ 0x6 bytes    C++
     mozjs.dll!js_InternalInvoke(JSContext * cx=0x06563400, JSObject *
obj=0x03301620, int fval=0x04173020, unsigned int flags=0x00000000, unsigned
int argc=0x00000001, int * argv=0x0072edac, int * rval=0x0039d6c8)  Line 900 +
0x12 bytes    C++
     mozjs.dll!JS_CallFunctionValue(JSContext * cx=0x06563400, JSObject *
obj=0x03301620, int fval=0x04173020, unsigned int argc=0x00000001, int *
argv=0x0072edac, int * rval=0x0039d6c8)  Line 4957    C++
     xul.dll!nsJSContext::CallEventHandler(nsISupports * aTarget=0x00753ec0,
void * aScope=0x03301620, void * aHandler=0x04173020, nsIArray *
aargv=0x5e5ff964, nsIVariant * * arv=0x0039d77c)  Line 2164    C++
     xul.dll!nsGlobalWindow::RunTimeout(nsTimeout * aTimeout=0x74ac6e40)  Line
8407    C++
     xul.dll!nsGlobalWindow::TimerCallback(nsITimer * aTimer=0x07111880, void *
aClosure=0x74ac6e40)  Line 8752    C++
     xul.dll!nsTimerImpl::Fire()  Line 427 + 0x7 bytes    C++
     nspr4.dll!_PR_MD_UNLOCK(_MDLock * lock=0x007b8140)  Line 347    C
     xul.dll!nsThread::ProcessNextEvent(int mayWait=, int * result=)  Line 528 


8 years ago
Group: core-security

Comment 1

8 years ago
Please give us a sec to review these kind of bugs before making it visible to the public.

Comment 2

8 years ago
My fault, I meant to file it s-s. You can get the testcase from Brandon.

Comment 3

8 years ago
Any issues with posting the test case here in the bug?

Comment 4

8 years ago
Could we post the test case in the bug?
(In reply to comment #4)
> Could we post the test case in the bug?

Sadly, no, as it's too large... See bug 532246, comment #4.


8 years ago
Keywords: testcase
Marking blocking 1.9.3 beta+.  Once we get a chance to review the test case, can you please update with an ETA to fix?  Also, an owner?
blocking2.0: --- → beta1+
Reproduced this on 3.6, waiting on an m-c build to finish to debug.

Comment 8

8 years ago
Reproduced as well. Will find dvander to coordinate.
Assignee: general → dvander
Neither Andreas nor I could make a shell test case out of this. So far every crash I've been able to trigger is in the browser, with either an OOM or some kind of massive heap corruption. Usually I die in the GC or in the cycle collector.

I put an alert() inside the useBadPtr function, and we crashed before the box ever showed up, so this might still be a JS bug. Will look further tomorrow.

Comment 10

8 years ago


8 years ago
Whiteboard: [sg:critical?] → [sg:critical?][critsmash:investigating]
Valgrind probably won't help unless we can get Firefox running w/ WMP and Java plugins on Wine in Linux. I did try the native Linux client, and it does crash, but it looked unrelated and in the plugin.

Last Tuesday I got record and replay working (and actually used it to debug another sg:crit), but I had trouble reproducing this one on debug builds.

I'll take a full shot at this tomorrow (I've been dedicating Tuesdays to security bugs).
I see three different failures. First:

> 6FC0E641  call        dword ptr [__imp__calloc (6FC9F188h)] 
> 6FC0E647  mov         dword ptr [eax+4],ebx

EAX is NULL - OOM failure. This is in the tracer, while importing slots from RecordTree().

Second: 1.9.2 only, I get crashes in the cycle collector because GCGraphBuilder's initialization can OOM, but this is never checked. This results in NULL derefs inside NSPR's PLD hash functions.

Third: The browser abruptly exits, with an "out of memory" line in the console.

For 1.9.3, with dom.ipc.plugins.enabled = false, it abrupt-dies with OOM after refreshing the page about 10 times. With dom.ipc.plugins.enabled = true, we reliably crash from OOM in the tracer.

Without being able to reproduce a crash like comment #0 (or get a minidump or crash-stats of it), I can't tell whether this is actually exploitable - certainly it's a denial of service though.
Assignee: dvander → general

Comment 13

8 years ago
(In reply to comment #11)
> Valgrind probably won't help unless we can get Firefox running w/ WMP and Java
> plugins on Wine in Linux.

How about Purify, then? That should work, right?
I don't see any evidence of memory corruption.
So, what's next here.  Need to get motion here.
This should definitely stay hidden, but unless someone is able to reproduce a memory corruption bug (i.e. not a NULL crash right after an allocation), it's not sg:critical. We could file bugs on all the OOM failures and then see if the test case does something different after fixing them, but the tracer basically ignores OOM handling.

We could also run Purify per comment #13 as a sanity check to make sure nothing crazy is going on.
OK.  David, are you going to run purify, or should we find someone else to do it?

Appreciate the help here.
David, purify?  Please stay on top of these.  :)
Please find someone else to do it, if possible - I don't have Purify and have never used it, and am pretty swamped at the moment.


8 years ago
blocking2.0: beta1+ → beta2+

Comment 20

8 years ago
I'll run Purify.
Assignee: general → sayrer
status1.9.1: --- → ?
status1.9.2: --- → wanted


7 years ago
blocking2.0: beta2+ → betaN+
Sayre, did you find a new owner here?


7 years ago
Whiteboard: [sg:critical?][critsmash:investigating] → [sg:critical?][critsmash:investigating][stale]
Sayre is still going to get to this.


7 years ago
Whiteboard: [sg:critical?][critsmash:investigating][stale] → [sg:critical?][critsmash:investigating][stale][needs Purify]
Whiteboard: [sg:critical?][critsmash:investigating][stale][needs Purify] → [sg:critical?][critsmash:investigating][stale][needs Purify][softblocker]
Sounds like no one's reproduced this in a while. We need to run this under purify on windows to see what's going on.
Whiteboard: [sg:critical?][critsmash:investigating][stale][needs Purify][softblocker] → [sg:needinfo][critsmash:investigating][stale][needs Purify][softblocker]

This bug is one of 19 being moved from blocking2.0:betaN+ to blocking2.0:- as we reached the endgame of Firefox 4. The rationale for the move is:

 - the bug had been identified as a "soft" blocker which could be fixed in some follow up release
 - the bug had been identified as one requiring beta coverage, thus is not appropriate for a ".x" stability & security release

The owner of the bug may wish to renominate for .x consideration.
blocking2.0: betaN+ → .x+
(er updating flag to "-" as per previous comment!)
blocking2.0: .x+ → -
Can we close this?  The crash was in the trace recorder, which is gone afaik.
TraceMonkey is gone.
Last Resolved: 5 years ago
Resolution: --- → WORKSFORME


2 years ago
Group: core-security → core-security-release
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.