Closed Bug 503286 (CVE-2009-2477) Opened 15 years ago Closed 15 years ago

browser crash when search suggestions show [@ js_Interpret ] [@ js_Execute]

Categories

(Core :: JavaScript Engine, defect)

1.9.1 Branch
defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla1.9.2a1

People

(Reporter: zbyte, Assigned: mrbkap)

References

()

Details

(5 keywords, Whiteboard: [sg:critical] fixed-in-tracemonkey)

Crash Data

Attachments

(8 files, 1 obsolete file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729) AutoPager/0.5.2.2 (http://www.teesoft.info/)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729) AutoPager/0.5.2.2 (http://www.teesoft.info/)

If start type search request in main form browser crash immediately. Crash only on some requests.

Reproducible: Always

Steps to Reproduce:
1. Go to www.aport.ru
2. In input form type one charater: 't'
3. Browser crash immediately.
Actual Results:  
Browser crash immediately.

Expected Results:  
Search suggestions showed
Confirmed on Windows Vista. I'll try to find some bug history.
Regression range: http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=fb5635f0d184&tochange=4a34c6235bb7
Assignee: nobody → general
Status: UNCONFIRMED → NEW
Component: General → JavaScript Engine
Ever confirmed: true
Product: Firefox → Core
QA Contact: general → general
Summary: browser crash when search suggestions show (AJAX) → browser crash when search suggestions show (AJAX) [@ js3250.dll@0x86f41 ]
Version: unspecified → 1.9.1 Branch
Trunk crash ID: http://crash-stats.mozilla.com/report/index/2afc6ae4-a95d-424d-b079-ef6fc2090709?p=1
Summary: browser crash when search suggestions show (AJAX) [@ js3250.dll@0x86f41 ] → browser crash when search suggestions show (AJAX) [@ js_Interpret ]
Can confirm this on Windows XP. Highly reproducible.
Confirmed on OSX with 3.5 and latest 1.9.2 trunk

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2a1pre) Gecko/20090709 Minefield/3.6a1pre
A first minimized version. Not completely minimized, but without referenced files and without HttpRequest.
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
bp-f8062a2b-f1bd-4a43-90b3-322de2090709
OS: Windows Server 2003 → All
Hardware: x86 → All
Flags: wanted1.9.1.x?
Flags: blocking1.9.1.1?
Title of bug is incorrect now. No AJAX involved. Javascript with string processing and innerHTML.
Problem is still present in the latest tracemonkey.
Summary: browser crash when search suggestions show (AJAX) [@ js_Interpret ] → browser crash when search suggestions show [@ js_Interpret ] [@ js_Execute]
Attachment #387713 - Attachment is obsolete: true
FTR, the line numbers for strict warnings and errors are totally borked for that file. Also, it dies in the function escapeData right after the "avto ??????" entry. I couldn't really reduce it anymore, anything I do stops crashing.
Attached file debug session
Looks like the content sink might be at fault here...
This is a JS engine bug dealing with deep bailing not properly restoring the return value from the result of the (fast native) escape function. We then try to do something with the uninitialized memory and crash in the interpreter.
(In reply to comment #13)
> Created an attachment (id=387732) [details]
> debug session
> 
> Looks like the content sink might be at fault here...

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x4000003b
0x00177d5c in JS_HashTableRawRemove ()
(gdb) bt 
#0  0x00177d5c in JS_HashTableRawRemove ()
#1  0x00184fcd in js_FreeStack ()
#2  0x0013354b in JS_EvaluateUCScriptForPrincipals ()
#3  0x014e5f67 in std::__adjust_heap<__gnu_cxx::__normal_iterator<nsRefPtr<imgCacheEntry>*, std::vector<nsRefPtr<imgCacheEntry>, std::allocator<nsRefPtr<imgCacheEntry> > > >, int, nsRefPtr<imgCacheEntry>, bool (*)(nsRefPtr<imgCacheEntry> const&, nsRefPtr<imgCacheEntry> const&)> ()
...
Removed a little bit, but crash is now very sensitive for more removal.
Attached file Final minimize.
Now document lookup anymore. Just string processing.
You guys rock. I was able to hack the shell into crashing with the last testcase!
Keywords: testcase
Attached patch Debugging patchSplinter Review
Here's the patch I used to make the shell crash on Lucas' testcase. Andreas: don't look!
Assignee: general → mrbkap
Status: NEW → ASSIGNED
Andreas mostly came up with this patch. I sort of followed along and verified that it fixes the crash. It also makes sense to me.

I don't have any clue how to make a trace-test for this... We can use Lucas' testcase as a mochitest, though.
Attachment #387787 - Flags: review?(jorendorff)
(of course, when I say mochitest up there, I mean crashtest.)
Since this bug is memory corruption and the 'escape' function is not exotic, other crashes could be in fact this bug (this bug is pretty serious).

I suspect bug 503144 being a duplicate of this. And I have seen another crash report, which could be a duplicate of this (I have to look that up).

Lucas
(In reply to comment #23)
> Since this bug is memory corruption and the 'escape' function is not exotic,
> other crashes could be in fact this bug (this bug is pretty serious).
> 
> I suspect bug 503144 being a duplicate of this. And I have seen another crash
> report, which could be a duplicate of this (I have to look that up).
> 
> Lucas

Right, the trend with this recent spill of JS crashes are all foreign sites making use of escape();
Just a question. Could the same bug appear with other builtin functions, like unescape? Or, does the patch solve all builtin function problems?

I was searching in crash sites and found something with an 'unescape' but without an 'escape'.

Lucas
Comment on attachment 387787 [details] [diff] [review]
Fix Andreas came up with

Is the declaration of deepBailSp missing?

r=me assuming that's the only thing.
Attachment #387787 - Flags: review?(jorendorff) → review+
(In reply to comment #25)
> Just a question. Could the same bug appear with other builtin functions, like
> unescape? Or, does the patch solve all builtin function problems?

The patch fixes all builtin functions.
From the duped bug 504001 , 
This bug has reliable exploit code on milw0rm that results in code execution.
http://milw0rm.com/exploits/9137
Can we get the fix merged over to m-c, bitte?
Flags: blocking1.9.1.1? → blocking1.9.1.1+
Group: core-security
Not sure what the internal policy is on publicly known exploits and hiding bugs or not. Someone versed in policy stuff please decide whether to unhide or not :)
Looking at the exploit code and our test cases, I think this is self-inflicted and we should have hidden the bug earlier. But this is very hard to judge to be hones.t I wouldn't entire exclude fuzzing or random heap spraying as method of discovery. Maybe someone with more experience on how such exploits are discovered wants to weigh in.
It would seem that the milw0rm exploit code is based on the testcases for this bug.   When you look at the crash details in a debugger, it's pretty clear that it's exploitable with a heap spray to the access violation address in question.
http://hg.mozilla.org/mozilla-central/rev/dc402f0a1122
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
I don't know know anything about the usual policy for hiding bugs, but in general, whether or not you publish something like that, security by obscurity in general is bad. There are always hackers out there trying to make a name for themselves and they'll throw every combination of fuzzers to find an exploit and make a name for themselves. Even if these testcases weren't visible, it was just a matter of time before someone would have gotten lucky and found the exploit.
(In reply to comment #36)
> I don't know know anything about the usual policy for hiding bugs, but in
> general, whether or not you publish something like that, security by obscurity
> in general is bad. There are always hackers out there trying to make a name for
> themselves and they'll throw every combination of fuzzers to find an exploit
> and make a name for themselves. Even if these testcases weren't visible, it was
> just a matter of time before someone would have gotten lucky and found the
> exploit.

True - but the _speed_ of fuzzers won't be faster than just heading to a not-yet-hidden-but-exploit-is-there-for-the-taking bug and taking the code to create an exploit. Note that the code in question apparently is identical to the testcase (if true), per comment #34.

The delay created by security through obscurity is bad, but it has its merits by providing some sort of delay, which is better than no delay at all (as in this case). Here we have an exploit created from a known bug that should have been hidden from the onset, reflecting probably on our shortcoming in some way, no one's mistake in particular.

But I digress...
yeah, well, linking the bugzilla bugs from crash-stats.mozilla.com is certainly an optimization, no matter how you look at it.
Group: core-security
Whiteboard: fixed-in-tracemonkey → [sg:critical] fixed-in-tracemonkey
Stack trace from Windows 7:
js3250.dll!js_Interpret(JSContext * cx=0x050b8450)  Line 4007 + 0x73 bytes
js3250.dll!js_Execute(JSContext * cx=0x050b8450, JSObject * chain=0x02881720, JSScript * script=0x051d0c78, JSStackFrame * down=0x00000000, unsigned int flags=0x00000000, int * result=0x00000000)  Line 1661 + 0x9 bytes
js3250.dll!JS_EvaluateUCScriptForPrincipals(JSContext * cx=0x050b8450, JSObject * obj=0x02881720, JSPrincipals * principals=0x04e6d4a4, const unsigned short * chars=0x068a1738, unsigned int length=0x00000139, const char * filename=0x004d1570, unsigned int lineno=0x00000003, int * rval=0x00000000)  Line 5157 + 0x19 bytes
gklayout.dll!nsJSContext::EvaluateString(const nsAString_internal & aScript={...}, void * aScopeObject=0x02881720, nsIPrincipal * aPrincipal=0x04e6d4a0, const char * aURL=0x004d1570, unsigned int aLineNo=0x00000003, unsigned int aVersion=0x00000000, nsAString_internal * aRetValue=0x00000000, int * aIsUndefined=0x001ae590)  Line 1682 + 0x42 bytes
gklayout.dll!nsScriptLoader::EvaluateScript(nsScriptLoadRequest * aRequest=0x06676380, const nsString & aScript={...})  Line 686 + 0x7a bytes
gklayout.dll!nsScriptLoader::ProcessRequest(nsScriptLoadRequest * aRequest=0x06676380)  Line 600 + 0x13 bytes
gklayout.dll!nsScriptLoader::ProcessScriptElement(nsIScriptElement * aElement=0x066ef95c)  Line 554 + 0x17 bytes
gklayout.dll!nsScriptElement::MaybeProcessScript()  Line 193 + 0x13 bytes
gklayout.dll!nsHTMLScriptElement::MaybeProcessScript()  Line 547 + 0xb bytes
gklayout.dll!nsHTMLScriptElement::DoneAddingChildren(int aHaveNotified=0x00000001)  Line 485
gklayout.dll!HTMLContentSink::ProcessSCRIPTEndTag(nsGenericHTMLElement * content=0x066ef938, int aMalformed=0x00000000)  Line 3096 + 0x12 bytes
gklayout.dll!SinkContext::CloseContainer(nsHTMLTag aTag=eHTMLTag_script, int aMalformed=0x00000000)  Line 1014 + 0x12 bytes
gklayout.dll!HTMLContentSink::CloseContainer(nsHTMLTag aTag=eHTMLTag_script)  Line 2376 + 0x11 bytes
gkparser.dll!CNavDTD::CloseContainer(nsHTMLTag aTag=eHTMLTag_script, int aMalformed=0x00000000)  Line 2762 + 0x26 bytes
gkparser.dll!CNavDTD::HandleEndToken(CToken * aToken=0x04cddca8)  Line 1641 + 0x13 bytes
gkparser.dll!CNavDTD::HandleToken(CToken * aToken=0x04cddca8)  Line 721 + 0xc bytes
gkparser.dll!CNavDTD::BuildModel(nsITokenizer * aTokenizer=0x004d1168, int aCanInterrupt=0x00000001, int aCountLines=0x00000001, const nsCString * __formal=0x0525137c)  Line 304 + 0xc bytes
gkparser.dll!nsParser::BuildModel()  Line 2452 + 0x5f bytes
gkparser.dll!nsParser::ResumeParse(int allowIteration=0x00000001, int aIsFinalChunk=0x00000000, int aCanInterrupt=0x00000001)  Line 2333 + 0xe bytes
gkparser.dll!nsParser::OnDataAvailable(nsIRequest * request=0x050ea158, nsISupports * aContext=0x00000000, nsIInputStream * pIStream=0x050eb0a8, unsigned int sourceOffset=0x00000000, unsigned int aLength=0x0000019c)  Line 2981 + 0x17 bytes
docshell.dll!nsDocumentOpenInfo::OnDataAvailable(nsIRequest * request=0x050ea158, nsISupports * aCtxt=0x00000000, nsIInputStream * inStr=0x050eb0a8, unsigned int sourceOffset=0x00000000, unsigned int count=0x0000019c)  Line 306 + 0x30 bytes
necko.dll!nsBaseChannel::OnDataAvailable(nsIRequest * request=0x004ebf80, nsISupports * ctxt=0x00000000, nsIInputStream * stream=0x050eb0a8, unsigned int offset=0x00000000, unsigned int count=0x0000019c)  Line 708 + 0x52 bytes
necko.dll!nsInputStreamPump::OnStateTransfer()  Line 508 + 0x40 bytes
necko.dll!nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream * stream=0x050eb0a8)  Line 398 + 0xb bytes
xpcom_core.dll!nsInputStreamReadyEvent::Run()  Line 112
xpcom_core.dll!nsThread::ProcessNextEvent(int mayWait=0x00000001, int * result=0x001af010)  Line 527 + 0x19 bytes
xpcom_core.dll!NS_ProcessNextEvent_P(nsIThread * thread=0x00414cc8, int mayWait=0x00000001)  Line 230 + 0x16 bytes
gkwidget.dll!nsBaseAppShell::Run()  Line 170 + 0xc bytes
tkitcmps.dll!nsAppStartup::Run()  Line 193 + 0x1c bytes
xul.dll!XRE_main(int argc=0x00000004, char * * argv=0x009cb0a0, const nsXREAppData * aAppData=0x009cfe70)  Line 3369 + 0x25 bytes
firefox.exe!NS_internal_main(int argc=0x00000004, char * * argv=0x009cb0a0)  Line 156 + 0x12 bytes
firefox.exe!wmain(int argc=0x00000004, wchar_t * * argv=0x009cc758)  Line 110 + 0xd bytes
firefox.exe!__tmainCRTStartup()  Line 583 + 0x19 bytes
firefox.exe!wmainCRTStartup()  Line 403
kernel32.dll!75df3f39() 	
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
ntdll.dll!776d0409() 	
ntdll.dll!776d03dc() 	

jsinterp.c:4007
if (!JSVAL_IS_PRIMITIVE(lval))
        DEFAULT_VALUE(cx, -2, JSTYPE_VOID, lval);
    if (!JSVAL_IS_PRIMITIVE(rval))
-->     DEFAULT_VALUE(cx, -1, JSTYPE_VOID, rval);
    if ((cond = JSVAL_IS_STRING(lval)) || JSVAL_IS_STRING(rval)) {
        if (cond) {
            str = JSVAL_TO_STRING(lval);
            str2 = js_ValueToString(cx, rval);
Not able to run calc.exe via the exploit posted on Windows 7 RC.
This patch needs to get into 1.9.1 ASAP.
blocking1.9.1: --- → ?
Target Milestone: --- → mozilla1.9.2a1
Attachment #387787 - Flags: approval1.9.1.1?
Comment on attachment 387787 [details] [diff] [review]
Fix Andreas came up with

This patch doesn't apply cleanly to the 1.9.1 branch.
Attachment #387787 - Flags: approval1.9.1.1?
Attached patch For 1.9.1Splinter Review
The merge was pretty trivial, though!
Attachment #388437 - Flags: review+
Attachment #388437 - Flags: approval1.9.1.1?
I'm not sure what's going on with flags/keywords... But I landed http://hg.mozilla.org/releases/mozilla-1.9.1/rev/a1a6b17a22da (with a crashtest) and also http://hg.mozilla.org/mozilla-central/rev/ddb8d512ede1 on trunk.
Keywords: fixed1.9.1.1
just ran this from last night's nightly, and still crashing on the testcase.
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-1.9.1/

mac.dmg dated 04:45, July 13th, 2009.

Did this not get picked up by the builder?
verified fixed in latest hourly build.

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.1pre) Gecko/20090714

from:
http://hg.mozilla.org/releases/mozilla-1.9.1/rev/f223409207c0

looking at the time I pasted above, it's not surprising the fix was not in that build (checkin was 11 hours later).
Attachment #388437 - Flags: approval1.9.1.1? → approval1.9.1.1+
I asked Ben to respin 1.9.1 nightlies.

Blake: can you also land this on GECKO191_20090623_RELBRANCH in case we decide to minibranch?
blocking1.9.1: ? → ---
I made the first test case, but I am not from Mozilla. If a good reproducible crash is sufficient to turn the security flag on, then bug 502648 (flash bug) should also get the security flag on. A bug no one is working on, yet.

Lucas
If it's reproducible and the stack trace shows signs of exploitability, yes.  Bug 502648 looks like a null deref, which is not exploitable.  See http://www.squarefree.com/2006/11/02/determining-whether-a-crash-looks-exploitable/ for how I evaluate crash stacks.
I only volunteer to make some test cases. Someone from Mozilla should have done this check and added it to bug 502648 (I will copy this info now).
A good, reproducible testcase is sufficient to run through a debugger and get a good idea whether it's exploitable or not. Comment 14 is around when this turned into a security bug.

bug 502648 looks like a null dereference which are not exploitable (usually -- sometimes the particular testcase results in a near-null but the bug might behave differently in other cases).
(In reply to comment #50)
> I only volunteer to make some test cases.

And it's much appreciated!! Once we have a testcase everything else is easy (often including the fix). Just keep sticking the testcase keyword up there when you do and it shows up in our triage queries.
Maybe off topic, but I don't know where to ask.

The site:

http://crash-stats.mozilla.com/

Has crashed per URL, but only for FF3.1b2. I can't get a list for FF3.5. Is this deliberate (for security)?

I managed to produce bug 502648 from that list, but I don't have any reproduction work now. There is nothing interesting in bugzilla anymore.

Lucas
(In reply to comment #53)
> Has crashed per URL, but only for FF3.1b2. I can't get a list for FF3.5. Is
> this deliberate (for security)?

No, it's non-deliberate, it's a bug with the site. :)
verified FIXED on builds:

...for Shiretoko
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.1pre) Gecko/20090715 Shiretoko/3.5.1pre (.NET CLR 3.5.30729) ID:20090715044728

and

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1pre) Gecko/20090613 Shiretoko/3.5pre ID:20090613031011

...for trunk
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20090714 Minefield/3.6a1pre (.NET CLR 3.5.30729) ID:20090714054201

and

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2a1pre) Gecko/20090715 Minefield/3.6a1pre ID:20090715031744
Status: RESOLVED → VERIFIED
Flags: wanted1.9.1.x?
Verified FIXED with MacOSX 3.5.1 candidate build.
I just installed the 3.5.1 (bild1) from the beta channel, and tested against
the exploit code, and the crash don't happened in my Windows Vista machine.
The exploit seems to be solved.
For bug searching ease, both http://www.milw0rm.com/exploits/9158 and http://www.milw0rm.com/exploits/9181 exploit this bug and are fixed in Firefox 3.5.1 (and never affected Firefox 3.0.x or earlier).
Alias: CVE-2009-2477
Flags: wanted1.9.0.x-
Crash Signature: [@ js_Interpret ] [@ js_Execute]
Filter on qa-project-auto-change:

Bug in removed tracer code, setting in-testsuite- flag.
Flags: in-testsuite-
You need to log in before you can comment on or make changes to this bug.