Closed Bug 475478 Opened 16 years ago Closed 16 years ago

Unsigned integer overflow involving uneval of an array/array.join

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
critical

Tracking

()

RESOLVED INVALID

People

(Reporter: gkw, Assigned: igor)

Details

(Keywords: testcase)

I pushed up jsfunfuzz-running iterations by twice as per normal and hit this bad bug. x = this; undefined &= /x/g ; undefined -= 1.2e3; eval("undefined >>>=x"); this.__defineGetter__("x", function ()undefined); eval("uneval(Array(x));"); eventually causes this in opt js shell with and without "-j": js-opt-tm-intelmac(37177) malloc: *** mmap(size=2397048832) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug 175b.js:6: out of memory Thanks gal for helping to debug this issue. gal mentions that we seem to be spending "a ton of time in Array.join, we loop over an entire integer range and eventually run OOM." Security-sensitive because it is suspected this is exploitable. [13:15] gal> (gdb) p length [13:15] gal> $5 = 4294966096 [13:15] gal> (gdb) p index [13:15] gal> $6 = 19212946
Flags: blocking1.9.1?
Some scary stuff is happening here. I suggest marking this security critical until we figured out whats going on.
Breakpoint 3, 0x0002a976 in array_join_sub (cx=0x30bbf0, obj=0x291160, op=TO_SOURCE, sep=0x0, rval=0x81424c) at ../jsarray.cpp:1236 1236 JSString *sep, jsval *rval) (gdb) n 1247 JS_CHECK_RECURSION(cx, return JS_FALSE); (gdb) n 1249 ok = js_GetLengthProperty(cx, obj, &length); (gdb) n 1250 if (!ok) (gdb) p ok $9 = 1 (gdb) p length $10 = 4294966096
This occurs in 1.9.0.x branch too: $ ./js-opt-moz190-intelmac js> x = this; [object global] js> undefined &= /x/g ; 0 js> undefined -= 1.2e3; -1200 js> eval("undefined >>>=x"); 4294966096 js> this.__defineGetter__("x", function ()undefined); js> eval("uneval(Array(x));"); js-opt-moz190-intelmac(39329) malloc: *** mmap(size=2397048832) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug typein:6: out of memory js>
Flags: blocking1.9.0.7?
Assignee: general → igor
In the test case after eval("undefined >>>=x"); the undefined becomes 4294966096. Then the code does Array(x). Since at that point a getter is defined for x that returns undefined, that is equivalent to Array(undefined) or Array(4294966096). Then the code tries to uneval this array with the length set to 4294966096. For that the code loops constructing a growing buffer that should eventually hold 4294966096 commas. On 32-bit systems that will fail at some point with OOM. So OOM is the correct behavior here. Note that in a browser or shell with enabled timeout a too slow script will be reported. Thus I mark the bug as invalid. Note that in principle the code can report an error earlier if it detects that the length of the buffer would exceed the maximum for the JS string length. But that would mean that the getters or toString for some elements of the array would not be called resulting in observable behavior change. So I am not sure that it worth to bother with this.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → INVALID
Group: core-security
Flags: blocking1.9.0.7?
Flags: blocking1.9.1?
You need to log in before you can comment on or make changes to this bug.