Last Comment Bug 622015 - (CVE-2011-0056) JavaScript Atom Invalid Index Vulnerability -- iDefense [V-ikgwbx1hqs]
: JavaScript Atom Invalid Index Vulnerability -- iDefense [V-ikgwbx1hqs]
[sg:critical]hardblocker fixed-in-tra...
: verified1.9.1, verified1.9.2
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: unspecified
: All All
: -- critical (vote)
: ---
Assigned To: Igor Bukanov
: Jason Orendorff [:jorendorff]
Depends on:
  Show dependency treegraph
Reported: 2010-12-29 16:00 PST by Reed Loden [:reed] (use needinfo?)
Modified: 2011-03-29 19:29 PDT (History)
12 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

v1 (72.37 KB, patch)
2010-12-30 11:04 PST, Igor Bukanov
no flags Details | Diff | Splinter Review
v2 (107.40 KB, patch)
2010-12-30 14:53 PST, Igor Bukanov
no flags Details | Diff | Splinter Review
two-liner fix (1.49 KB, patch)
2011-01-03 11:25 PST, Igor Bukanov
brendan: review+
Details | Diff | Splinter Review
fix for 19[12] (1.57 KB, patch)
2011-01-17 07:32 PST, Igor Bukanov
christian: approval1.9.2.14+
christian: approval1.9.1.17+
Details | Diff | Splinter Review
Fix for 1.9.0 (606 bytes, patch)
2011-02-14 06:43 PST, Mike Hommey [:glandium]
igor: review+
Details | Diff | Splinter Review

Description Reed Loden [:reed] (use needinfo?) 2010-12-29 16:00:10 PST
Created attachment 500274 [details]

iDefense VCP Submission V-ikgwbx1hqs


Mozilla Firefox JavaScript Atom Invalid Index Vulnerability


Remote exploitation of a memory corruption vulnerability in Mozilla Organization's FireFox could allow an attacker to execute arbitrary code with the privileges of the current user.

The vulnerability occurs in the JavaScript engine (SpiderMonkey) of Mozilla FireFox. When compiling javascript, the Mozilla engine produces bytecode that is later interpreted in a virtual machine. Strings and other literals (so called atoms) are stored in an atom map. Opcodes that use values from the atom map take a 16 bit immediate constant operand that is used as an index in the atom map array. When more than 64k atoms are used, special handling is required because a 16 bit value would not suffice to address the desired atom. Therefore, the engine frames the opcode with an "indexbaseX" and a "resetbase0" opcode that move the atoms pointer forward and backward respectively. When an exception is thrown in between the indexbase and resetbase opcodes, the atoms pointer does not get reset and the exception object of the catch block is read from an invalid memory address. This results in an exploitable memory corruption vulnerability. 


Exploitation of this vulnerability results in the execution of arbitrary code with the privileges of the user viewing the web page. To exploit this vulnerability, a targeted user must load a malicious webpage created by an attacker. An attacker typically accomplishes this via social engineering or injecting content into compromised, trusted sites. After the user visits the malicious web page, no further user interaction is needed.

In order to exploit this vulnerability, it is necessary control various structures at the location of the invalid reference. By performing a heap spray it is possible to populate memory with the needed structures and obtain reliable arbitrary code execution. 


Christian Holler
Comment 1 Robert Sayre 2010-12-29 17:41:04 PST
Word has it that Igor is the one to handle this. Let us know if this turns out to be wrong.
Comment 2 Luke Wagner [:luke] 2010-12-29 23:10:55 PST
Not blocking this bug, but it seems like we should reevaluate the space/time benefits of all this indexbase complexity.
Comment 3 Igor Bukanov 2010-12-30 08:13:02 PST
(In reply to comment #2)
> Not blocking this bug, but it seems like we should reevaluate the space/time
> benefits of all this indexbase complexity.

I am going to try 3-byte indexes and see how this affects interpreter-only benchmarks.
Comment 4 Igor Bukanov 2010-12-30 11:04:33 PST
Created attachment 500368 [details] [diff] [review]

Here is an untested work-in-progress.
Comment 5 Igor Bukanov 2010-12-30 14:53:57 PST
Created attachment 500411 [details] [diff] [review]

Here is another WIP - it still fails few tests during make check.
Comment 6 Igor Bukanov 2011-01-03 10:22:47 PST
The resulting patch for expanding the literal index to 3 bytes is too big to port it to branches. Apparently the macros to work with the bytecode do not abstract the literal index sufficiently to allow for a small and easy to test patch. So I will delegate that to the bug 622557 while focusing here on hopefully one-liner fix.
Comment 7 Igor Bukanov 2011-01-03 10:30:15 PST
A simpler test case that builds a function source with over 64K literals:

var src = "var a=[";
for(var i  = 0; i != 1e5; ++i)
    src += "'a"+i+"',";
src += "]; i = 'xyz';";
src += "try { x.y; return a; } catch(e) { return this[i]; }";

var x = { get y() { throw 0; }};
var xyz = 42;

assertEq(Function(src)(), 42);

It asserts/crashes in debug/optimized builds.
Comment 8 Igor Bukanov 2011-01-03 11:25:13 PST
Created attachment 500865 [details] [diff] [review]
two-liner fix

The fix adds missing re-initialization of atoms.
Comment 9 Brendan Eich [:brendan] 2011-01-03 13:13:19 PST
Comment on attachment 500865 [details] [diff] [review]
two-liner fix

Need back-porting, should be easy.

Comment 11 Igor Bukanov 2011-01-04 14:20:46 PST
The bug is definitely critical
Comment 12 Chris Leary [:cdleary] (not checking bugmail) 2011-01-06 23:07:40 PST
Comment 13 Reed Loden [:reed] (use needinfo?) 2011-01-17 00:01:00 PST
Guys, can we get this on the branches?
Comment 14 Christian Holler (:decoder) 2011-01-17 00:47:29 PST
Please note that the particular PoC attached here is a shell PoC only and won't run in browser (it might even fail in the shell, it was tested with Ubuntu and the shell from Firefox 3.6.11 release). Exploitation in the browser works the same as in shell but requires more complicated heap spraying to work reliable.

I won't ever publish the working exploit for the browser.
Comment 15 Christian Holler (:decoder) 2011-01-17 01:12:43 PST
Fyi, successful exploitation in the shell looks like this:

 Program received signal SIGSEGV, Segmentation fault.
 0x08177853 in js_Interpret (cx=0x81ba9e0) at jsops.cpp:2208
 2208                        ok = ((JSFastNative) fun->u.n.native)(cx, argc, vp);
 (gdb) print fun->u.n.native
 $1 = (JSNative) 0xdeadbeef
Comment 16 Igor Bukanov 2011-01-17 07:32:16 PST
Created attachment 504464 [details] [diff] [review]
fix for 19[12]

The patch is a trivial backport to 1.9.2, here is a plain diff between the trunk and it:

< @@ -6805,7 +6805,6 @@ END_CASE(JSOP_ARRAYPUSH)
<          // Handle exceptions as if they came from the imacro-calling pc.
<          regs.pc = regs.fp->imacropc();
<          regs.fp->clearImacropc();
> @@ -3069,7 +3069,6 @@ js_Interpret(JSContext *cx)
>          // Handle other exceptions as if they came from the imacro-calling pc.
>          regs.pc = fp->imacpc;
>          fp->imacpc = NULL;
<  #endif
< @@ -6834,6 +6833,9 @@ END_CASE(JSOP_ARRAYPUSH)
>      JS_ASSERT((size_t)((fp->imacpc ? fp->imacpc : regs.pc) - script->code) < script->length);
> @@ -3092,6 +3091,9 @@ js_Interpret(JSContext *cx)
Comment 17 Igor Bukanov 2011-01-17 07:36:24 PST
Comment on attachment 504464 [details] [diff] [review]
fix for 19[12]

The 192 patch applies as-is to 191.
Comment 18 christian 2011-01-18 12:46:17 PST
Comment on attachment 504464 [details] [diff] [review]
fix for 19[12]

a=LegNeato for and
Comment 21 Al Billings [:abillings] 2011-01-21 12:49:16 PST
Verified crash in with PoC and fix in Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20110121 Shiretoko/3.5.17pre ( .NET CLR 3.5.30729).

Same with and Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20110121 Namoroka/3.6.14pre ( .NET CLR 3.5.30729).
Comment 22 Mike Hommey [:glandium] 2011-02-14 06:43:18 PST
Created attachment 512152 [details] [diff] [review]
Fix for 1.9.0

Would that be enough for 1.9.0 ? (It looks like so ; at least the testcase doesn't crash anymore)
Comment 23 Igor Bukanov 2011-02-14 14:09:33 PST
Comment on attachment 512152 [details] [diff] [review]
Fix for 1.9.0

Please use diff -U8 the next time you attach the patch for a review to get more context.

Note You need to log in before you can comment on or make changes to this bug.