CVE-2009-2477: Just-in-time (JIT) JavaScript compiler allows remote attackers to execute arbitrary code

Bug #400557 reported by Micah Gersten
262
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Mozilla Firefox
Fix Released
Critical
firefox-3.5 (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

Binary package hint: firefox-3.5

Overview

The Just-in-time (JIT) JavaScript compiler in Mozilla Firefox 3.5 allows remote attackers to execute arbitrary code via a crafted document containing P and FONT elements.

Impact
CVSS Severity (version 2.0):
CVSS v2 Base Score:6.9 (MEDIUM) (AV:L/AC:M/Au:N/C:C/I:C/A:C) (legend)
Impact Subscore: 10.0
Exploitability Subscore: 3.4
CVSS Version 2 Metrics:
Access Vector: Locally exploitable; Victim must voluntarily interact with attack mechanism
Access Complexity: Medium
Authentication: Not required to exploit
Impact Type:Allows unauthorized disclosure of information; Allows unauthorized modification; Allows disruption of service

CVE References

Revision history for this message
In , Ria-klaassen (ria-klaassen) wrote :

Confirmed on Windows Vista. I'll try to find some bug history.

Revision history for this message
In , Ria-klaassen (ria-klaassen) wrote :
Revision history for this message
In , Ria-klaassen (ria-klaassen) wrote :
Revision history for this message
In , Ria-klaassen (ria-klaassen) wrote :
Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

Can confirm this on Windows XP. Highly reproducible.

Revision history for this message
In , AaronMT (aaron-train) wrote :

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

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

Created attachment 387713
Fairly minimized, standalone, no russion, no httprequest.

A first minimized version. Not completely minimized, but without referenced files and without HttpRequest.

Revision history for this message
In , Highmind63 (highmind63) wrote :

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

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

Title of bug is incorrect now. No AJAX involved. Javascript with string processing and innerHTML.

Revision history for this message
In , Ria-klaassen (ria-klaassen) wrote :

Problem is still present in the latest tracemonkey.

Revision history for this message
In , Highmind63 (highmind63) wrote :

Created attachment 387727
testcase, reduced a bit more.

Revision history for this message
In , Highmind63 (highmind63) wrote :

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.

Revision history for this message
In , Highmind63 (highmind63) wrote :

Created attachment 387732
debug session

Looks like the content sink might be at fault here...

Revision history for this message
In , Mrbkap (mrbkap) wrote :

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.

Revision history for this message
In , AaronMT (aaron-train) wrote :

(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&)> ()
...

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

Created attachment 387739
Reduces a little bit more, not much.

Removed a little bit, but crash is now very sensitive for more removal.

Revision history for this message
In , AaronMT (aaron-train) wrote :

Created attachment 387744
even slightly more reduced

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

Created attachment 387752
Final minimize.

Now document lookup anymore. Just string processing.

Revision history for this message
In , Mrbkap (mrbkap) wrote :

You guys rock. I was able to hack the shell into crashing with the last testcase!

Revision history for this message
In , Mrbkap (mrbkap) wrote :

Created attachment 387786
Debugging patch

Here's the patch I used to make the shell crash on Lucas' testcase. Andreas: don't look!

Revision history for this message
In , Mrbkap (mrbkap) wrote :

Created attachment 387787
Fix Andreas came up with

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.

Revision history for this message
In , Mrbkap (mrbkap) wrote :

(of course, when I say mochitest up there, I mean crashtest.)

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

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

Revision history for this message
In , AaronMT (aaron-train) wrote :

(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();

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

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

Revision history for this message
In , Jorendorff (jorendorff) wrote :

Comment on attachment 387787
Fix Andreas came up with

Is the declaration of deepBailSp missing?

r=me assuming that's the only thing.

Revision history for this message
In , Mrbkap (mrbkap) wrote :
Revision history for this message
In , Mrbkap (mrbkap) wrote :

(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.

Revision history for this message
In , Highmind63 (highmind63) wrote :

*** Bug 504001 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Wd-pobox (wd-pobox) wrote :

From the duped bug 504001 ,
This bug has reliable exploit code on milw0rm that results in code execution.
http://milw0rm.com/exploits/9137

Revision history for this message
In , Beltzner (beltzner) wrote :

Can we get the fix merged over to m-c, bitte?

Revision history for this message
In , Andreas Gal (gal) wrote :

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 :)

Revision history for this message
In , Andreas Gal (gal) wrote :

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.

Revision history for this message
In , Wd-pobox (wd-pobox) wrote :

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.

Revision history for this message
In , RobertSayre (sayrer) wrote :
Revision history for this message
In , Dtran (dtran) wrote :

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.

Revision history for this message
In , Gary-rumblingedge (gary-rumblingedge) wrote :

(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...

Revision history for this message
In , RobertSayre (sayrer) wrote :

yeah, well, linking the bugzilla bugs from crash-stats.mozilla.com is certainly an optimization, no matter how you look at it.

Revision history for this message
In , Tellrob (tellrob) wrote :
Download full text (4.8 KiB)

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 * req...

Read more...

Revision history for this message
In , Tellrob (tellrob) wrote :

Not able to run calc.exe via the exploit posted on Windows 7 RC.

Revision history for this message
In , Vladimir Vukicevic (vvuk) wrote :

This patch needs to get into 1.9.1 ASAP.

Revision history for this message
In , Mrbkap (mrbkap) wrote :

Comment on attachment 387787
Fix Andreas came up with

This patch doesn't apply cleanly to the 1.9.1 branch.

Revision history for this message
In , Mrbkap (mrbkap) wrote :

Created attachment 388437
For 1.9.1

The merge was pretty trivial, though!

Revision history for this message
In , Mrbkap (mrbkap) wrote :

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.

Revision history for this message
In , Rcampbell-mozilla (rcampbell-mozilla) wrote :

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?

Revision history for this message
In , Rcampbell-mozilla (rcampbell-mozilla) wrote :

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).

Revision history for this message
In , Beltzner (beltzner) wrote :

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?

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

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

Revision history for this message
In , Jruderman (jruderman) wrote :

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.

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

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).

Revision history for this message
In , Dveditz (dveditz) wrote :

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).

Revision history for this message
In , Dveditz (dveditz) wrote :

(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.

Revision history for this message
In , L-b-kruijswijk (l-b-kruijswijk) wrote :

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

Revision history for this message
In , Samuel-sidler+old (samuel-sidler+old) wrote :

*** Bug 504237 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Ludovic-mozillamessaging (ludovic-mozillamessaging) wrote :

*** Bug 504298 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Beltzner (beltzner) wrote :

(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. :)

Revision history for this message
In , Mozaakash (mozaakash) wrote :

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

Revision history for this message
In , Andreas Gal (gal) wrote :

Verified FIXED with MacOSX 3.5.1 candidate build.

Revision history for this message
In , Fernando Hartmann (matafagafo-yahoo) wrote :

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.

Revision history for this message
Micah Gersten (micahg) wrote :

Binary package hint: firefox-3.5

Overview

The Just-in-time (JIT) JavaScript compiler in Mozilla Firefox 3.5 allows remote attackers to execute arbitrary code via a crafted document containing P and FONT elements.

Impact
CVSS Severity (version 2.0):
CVSS v2 Base Score:6.9 (MEDIUM) (AV:L/AC:M/Au:N/C:C/I:C/A:C) (legend)
Impact Subscore: 10.0
Exploitability Subscore: 3.4
CVSS Version 2 Metrics:
Access Vector: Locally exploitable; Victim must voluntarily interact with attack mechanism
Access Complexity: Medium
Authentication: Not required to exploit
Impact Type:Allows unauthorized disclosure of information; Allows unauthorized modification; Allows disruption of service

Revision history for this message
In , Mrbkap (mrbkap) wrote :

*** Bug 504810 has been marked as a duplicate of this bug. ***

Micah Gersten (micahg)
visibility: private → public
Changed in firefox-3.5 (Ubuntu):
status: New → Fix Committed
Revision history for this message
In , Mozaakash (mozaakash) wrote :

*** Bug 504810 has been marked as a duplicate of this bug. ***

Changed in firefox:
status: Unknown → Fix Released
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

xulrunner-1.9.1 (1.9.1.1+build1+nobinonly-0ubuntu1) karmic; urgency=low

  * security/stability update v1.9.1.1 build1 (FIREFOX_1_5_1_BUILD1)
  * tighten depends of xulrunner-1.9.1-dev; use xulrunner-1.9.1 (= ${binary:Version})
    - update debian/control
  * prepare package for launchpad translations; open up EM_TRANSLATION
    versions (min: 1.9.1 / max: 1.9.1.*)
    - update debian/rules

 -- Alexander Sack < <email address hidden>> Thu, 16 Jul 2009 18:26:43 +0200

Changed in firefox-3.5 (Ubuntu):
status: Fix Committed → Fix Released
Revision history for this message
In , Dveditz (dveditz) wrote :

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).

Revision history for this message
In , Dveditz (dveditz) wrote :
Revision history for this message
In , Samuel-sidler+old (samuel-sidler+old) wrote :

*** Bug 507075 has been marked as a duplicate of this bug. ***

Changed in firefox:
importance: Unknown → Critical
Revision history for this message
In , Choller (choller) wrote :

Filter on qa-project-auto-change:

Bug in removed tracer code, setting in-testsuite- flag.

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.