Closed Bug 558414 Opened 14 years ago Closed 12 years ago

JS engine crashes with heap-spray testcase

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME
Tracking Status
blocking2.0 --- -
status1.9.2 --- wanted
status1.9.1 --- ?

People

(Reporter: benjamin, Assigned: sayrer)

References

Details

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

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   
C++

another:

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
   C++
     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   
C++
     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++
     xul.dll!nsCOMPtr<nsPIDOMWindow>::nsCOMPtr<nsPIDOMWindow>(const
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 
  C++
Group: core-security
Please give us a sec to review these kind of bugs before making it visible to the public.
My fault, I meant to file it s-s. You can get the testcase from Brandon.
Any issues with posting the test case here in the bug?
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.
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.
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.
valgrind?
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
(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.
blocking2.0: beta1+ → beta2+
I'll run Purify.
Assignee: general → sayrer
blocking2.0: beta2+ → betaN+
Sayre, did you find a new owner here?
Whiteboard: [sg:critical?][critsmash:investigating] → [sg:critical?][critsmash:investigating][stale]
Sayre is still going to get to this.
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]
** PRODUCT DRIVERS PLEASE NOTE **

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.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → WORKSFORME
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.