Last Comment Bug 658805 - Shell trap() should bounds-check
: Shell trap() should bounds-check
: assertion, testcase
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Trunk
: x86 Mac OS X
-- critical (vote)
: ---
Assigned To: general
: Jason Orendorff [:jorendorff]
Depends on:
Blocks: jsfunfuzz 429239
  Show dependency treegraph
Reported: 2011-05-21 10:28 PDT by Gary Kwong [:gkw] [:nth10sd]
Modified: 2011-09-07 01:05 PDT (History)
5 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Description User image Gary Kwong [:gkw] [:nth10sd] 2011-05-21 10:28:39 PDT
function tryItOut(code) {
    var printStealer = "v='';function t(){}";
    prefix = getBytecodeOffsets + printStealer + "function fff(){" + code + "}";
    r0 = sandboxResult(prefix + "(uneval(getBytecodeOffsets()))");
    offsets = eval(r0);
    for (i = 0; offsets.length; ++i) {
        offset = offsets[i].offset;
        trapStr = "trap(fff," + offset + ",'');";
        sandboxResult(prefix + trapStr + "f");
function getBytecodeOffsets() {
    disassembly = disassemble();
    var lines = disassembly.split("n");
    var offsets = [];
    for (i = 0; i < lines.length; ++i) {
        var op = lines[i].substr().split("")[0];
        offset = parseInt(lines[i], 0);
        if ((p = "o" && op != "" & op != "")) {
                offset: offset,
                p: p
    return offsets;
function sandboxResult(code) {
    try {
        sandbox = newGlobal("new-compartment");
        result = eval(code, sandbox);
        resultStr = "" + result;
    } catch (e) {}
    return resultStr;

asserts js debug shell on JM changeset 33f1ad45ccb8 with -m, -a and -d at Assertion failure: isGCThing(),

Pass in the testcase as a CLI argument to reproduce.

(gdb) bt
#0  0x001f9ae6 in JS_Assert (s=0x3acad4 "isGCThing()", file=0x38d3e4 "/Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsvalue.h", ln=625) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsutil.cpp:86
#1  0x000bcc15 in js::Value::toGCThing (this=0x8d3da8) at jsvalue.h:625
#2  0x0006ed37 in JSCompartment::sweep (this=0x2341800, cx=0x817990, releaseInterval=0) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jscompartment.cpp:496
#3  0x000b86c3 in SweepCrossCompartmentWrappers (cx=0x817990) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsgc.cpp:2209
#4  0x000b9b83 in MarkAndSweep (cx=0x817990, comp=0x0, gckind=GC_LAST_CONTEXT) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsgc.cpp:2392
#5  0x000b9e4b in GCCycle (cx=0x817990, comp=0x0, gckind=GC_LAST_CONTEXT) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsgc.cpp:2675
#6  0x000ba192 in js_GC (cx=0x817990, comp=0x0, gckind=GC_LAST_CONTEXT) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsgc.cpp:2746
#7  0x0006c90f in js_DestroyContext (cx=0x817990, mode=JSDCM_FORCE_GC) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jscntxt.cpp:657
#8  0x000360d4 in JS_DestroyContext (cx=0x817990) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/jsapi.cpp:1034
#9  0x0000f942 in DestroyContext (cx=0x817990, withGC=true) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/shell/js.cpp:5823
#10 0x00017873 in main (argc=4, argv=0xbffff810, envp=0xbffff824) at /Users/fuzz2/Desktop/jsfunfuzz-dbg-32-jm-69810-33f1ad45ccb8/compilePath/js/src/shell/js.cpp:6110
Comment 1 User image Gary Kwong [:gkw] [:nth10sd] 2011-05-21 10:31:23 PDT
Tested to reproduce on a 32-bit Mac OS X 10.6 shell, but could not reproduce on a 32-bit shell in Linux.
Comment 2 User image Brian Hackett (:bhackett) 2011-05-21 22:43:53 PDT
TM bug, though fixed in JM (this is outside the JIT and may want to land to TM separately before merging TI into TM).  The shell-only trap() function takes a pc offset but did not bounds check it against the script, and JS_SetTrap had no assert the pc was in range.  If an out of range argument was passed to trap(), it would end up trapping/untrapping some random location in memory (in this case, a crossCompartmentWrappers table).  This adds an assert to JS_SetTrap, and a bounds check to the trap() function.
Comment 3 User image Gary Kwong [:gkw] [:nth10sd] 2011-09-07 01:05:40 PDT
(In reply to Brian Hackett from comment #2)
> TM bug, though fixed in JM (this is outside the JIT and may want to land to
> TM separately before merging TI into TM).

This bug may be resolved since TI has landed on m-c, but I'm not sure about the resolution. Since it landed on m-c, I'm going with FIXED.

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