Closed Bug 633890 Opened 13 years ago Closed 13 years ago

Assertion failure: prop == (JSProperty*) shape

Categories

(Core :: JavaScript Engine, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
blocking2.0 --- .x+

People

(Reporter: bc, Assigned: jorendorff)

References

()

Details

(Keywords: assertion, Whiteboard: [fixed-in-tracemonkey])

Attachments

(1 file)

1. http://www.msnbc.msn.com/id/41540062/ns/business-retail/?gt1=43001
2. Assertion failure: prop == (JSProperty*) shape, at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:12859

Reproducble on Windows, Mac, Linux. If it doesn't assert, try reloading.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x06790c87 in JS_Assert (s=0x6ca3d25 "prop == (JSProperty*) shape", file=0x6ca1d3c "/work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp", ln=12859) at /work/mozilla/builds/2.0.0/mozilla/js/src/jsutil.cpp:80
80	    *((int *) NULL) = 0;  /* To continue from here in GDB: "return" then "continue". */
(gdb) bt
#0  0x06790c87 in JS_Assert (s=0x6ca3d25 "prop == (JSProperty*) shape", file=0x6ca1d3c "/work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp", ln=12859) at /work/mozilla/builds/2.0.0/mozilla/js/src/jsutil.cpp:80
#1  0x067be09b in js::GetPropertyWithNativeGetter (cx=0x23754960, obj=0x25b7d7e0, shape=0x250ab0a8, vp=0xbfffb6c8) at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:12859
#2  0x20047afc in ?? ()
#3  0x067b4488 in js::ExecuteTrace (cx=0x23754960, tm=0xdf3280, f=0x256a6c9c, state=@0xbfffb7d8) at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:6555
#4  0x067c2746 in js::ExecuteTree (cx=0x23754960, tm=0xdf3280, f=0x256a6c9c, inlineCallCount=@0xbfffb9c4, innermostNestedGuardp=0xbfffb8dc, lrp=0xbfffb8e0) at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:6663
#5  0x067d3ddf in js::RecordTracePoint (cx=0x23754960, tm=0xdf3280, inlineCallCount=@0xbfffb9c4, blacklist=0xbfffb9cb, execAllowed=true) at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:16803
#6  0x067d42b0 in js::MonitorTracePoint (cx=0x23754960, inlineCallCount=@0xbfffb9c4, blacklist=0xbfffb9cb, traceData=0x255f6128, traceEpoch=0x255f612c, loopCounter=0x255f6130, hits=1) at /work/mozilla/builds/2.0.0/mozilla/js/src/jstracer.cpp:17046
#7  0x068aea40 in RunTracer (f=@0xbfffba30, ic=@0x255f6114) at /work/mozilla/builds/2.0.0/mozilla/js/src/methodjit/InvokeHelpers.cpp:1024
#8  0x068aed30 in js::mjit::stubs::InvokeTracer (f=@0xbfffba30, ic=0x255f6114) at /work/mozilla/builds/2.0.0/mozilla/js/src/methodjit/InvokeHelpers.cpp:1115
#9  0x2008abde in ?? ()
#10 0x0683c775 in js::mjit::EnterMethodJIT (cx=0x23754960, fp=0x1000070, code=0x1f6cf000, stackLimit=0x108cab0) at /work/mozilla/builds/2.0.0/mozilla/js/src/methodjit/MethodJIT.cpp:748
#11 0x0683c894 in CheckStackAndEnterMethodJIT (cx=0x23754960, fp=0x1000070, code=0x1f6cf000) at /work/mozilla/builds/2.0.0/mozilla/js/src/methodjit/MethodJIT.cpp:774
#12 0x0683c9b4 in js::mjit::JaegerShot (cx=0x23754960) at /work/mozilla/builds/2.0.0/mozilla/js/src/methodjit/MethodJIT.cpp:791
#13 0x066b24ee in js::Interpret () at /work/mozilla/builds/2.0.0/mozilla/js/src/jsinterp.cpp:4700
#14 0x066c459f in js::RunScript (cx=0x23754960, script=0x256b1600, fp=0x1000030) at jsinterp.cpp:640
#15 0x066c65ca in js::Execute (cx=0x23754960, chain=0x23d300a0, script=0x256b1600, prev=0x0, flags=0, result=0x0) at jsinterp.cpp:1006

locally saved versions of the page don't assert due to (I think) security errors trying to run from disk. So, I can't yet get a reproducible test case.

1.9.2 asserts with Assertion failure: prop == (JSProperty*) sprop. See Bug 522521
Group: core-security
Hidden for investigation. This sounds bad.
Doesn't assert for me on x64 Linux after reloading a few times.
(In reply to comment #2)
> Doesn't assert for me on x64 Linux after reloading a few times.

Is that with tracemonkey or mozilla-central?

I just reproduced with 32bit and 64bit fedora 14 on mozilla-central with builds from this morning.
just reproduced again on mozilla-central and tracemonkey on mac os x. I had to reload once for each.
nominated due to Andreas' concern this might enable a drive by.
blocking2.0: --- → ?
blocking2.0: ? → .x
Bob, please grab someone on IRC if you get this in gdb -- need to debug a bit.

/be
This could be sg:crit. We need an analysis here. My plate is full sorry.
Jason said "Karate night" and had to run, but he said he'd take it. We believe this is #ifdef DEBUG code that calls lookupProperty which seems like it could call nsHTMLFormElementSH::NewResolve and mess with the tracer's carefully guarded invariants. If so, this bug is not sg:crit and not a blocker except to bc's life testing. It ought to be an easy NPOT(non-DEBUG)B fix.

/be
Assignee: general → jorendorff
If a resolve hook is causing this, I think that means it's a dup of bug 458271, and that might lead to a small test case. Certainly we shouldn't be asserting rules that we know we're not actually following.

Brendan suggested switching the assertion from obj->lookupProperty to something like SafeLookup. Sounds good to me.
Doesn't reproduce here (32-bit build on Windows).
bclary found a URL that reproduces this for me on Windows. It is:

http://www.msnbc.msn.com/id/41584626/ns/business-small_business/?GT1=43001
This triggers the same assertion with the same stack.

<!doctype html>

<form></form>
<form><input name="id"></form>

<script>
//var HOTLOOP = 8;
var x = document.forms[0], y = document.forms[1];
var forms = [];
for (var j = 0; j < 10000; j++)
    forms[j] = x;
forms[j] = y;
for (var i = 0; i < forms.length; i++)
    forms[i].id;
</script>
It is definitely a case of bug 458271. In this bug, I'll just weaken the assertion. I'll leave bug 458271 open for the real fix. (Which will follow Ff4, I imagine. This bug report tells us there is now a real-world web site tickling bug 458271, which is a little surprising and should make that a higher priority; but not high enough to block, I think.)

More in a second.
The bug does not lead to an exploitable crash or undefined behavior in the C++ sense. The situation is:

   - Two DOM objects x and y have the same shape.
   - They have the same prototype, P, which has a property P.id.
   - They have the same resolve hook, but it behaves differently for x vs. y.

At trace record time x.id is inherited from P; and at trace run time, we treat y just like x, since they're the same shape, even though y's resolve hook would have resolved an own property y.id, shadowing P.id. We skip calling the resolve hook on x. Wrong computation, no crash.

Given that it doesn't crash, is it exploitable some other way? I can't think of a plausible scenario. The only remote possibilities I can think of are:

  - Inasmuch as chrome code depends on getting right answers, when we
    give a wrong answer, that might be exploitable. But in this case we're
    talking about stuff like document.forms. Wrappers for such content nodes
    have x-ray behavior by default, which causes these resolve hooks to be
    skipped anyway. So the bug won't even occur. (We don't trace wrapper
    accesses either -- but that is little comfort since I suspect methodjit
    has the same bug.)

    There might be problems here I'm not seeing, but my hunch is we're OK.

  - It is just barely possible that some Web page somewhere contains both
    site-generated content and user-generated content, and scripts in the page
    distinguish the two by the presence or absence of a form field like
    this one. If such a site triggers this bug, it might trust user-generated
    content that it should not trust. It could amount to cross-site scripting
    in the worst case.

    This seems laughably unlikely, but proving that would be hard, maybe
    harder than just fixing the bug.
With resolver (see patch in bug 458271) this can be triggered in the shell:

var p = /./, x = resolver({}, p), y = resolver({lastIndex: 2}, p), v;
var a = [];
for (var i = 0; i < HOTLOOP; i++)
    a[i] = x;
a[HOTLOOP] = y;
for (i = 0; i < a.length; i++)
    v = a[i].lastIndex;
assertEq(v, 2);
Attached patch v1Splinter Review
This patch depends on resolver.
Attachment #513216 - Flags: review?(brendan)
Based on comment #9 etc this sounds like it should be opened up. Or am I missing something here?
Attachment #513216 - Flags: review?(brendan) → review+
Group: core-security
Comment on attachment 513216 [details] [diff] [review]
v1

Looking for approval, since the patch is extremely low-risk (#ifdef DEBUG only) and assertions are bad.
Attachment #513216 - Flags: approval2.0?
Attachment #513216 - Flags: approval2.0? → approval2.0+
http://hg.mozilla.org/tracemonkey/rev/711804514c8e
Whiteboard: [fixed-in-tracemonkey]
http://hg.mozilla.org/mozilla-central/rev/711804514c8e
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
I'd really like to make the following change:

--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -2054,7 +2054,7 @@ AssertValidPropertyCacheHit(JSContext *c
     }
     if (!ok)
         return false;
-    if (cx->runtime->gcNumber != sample || entry->vshape() != pobj->shape())
+    if (cx->runtime->gcNumber != sample)
         return true;
     JS_ASSERT(prop);
     JS_ASSERT(pobj == found);

because without it, AssertValidPropertyCacheHit really doesn't do its job. However, if we do that, the test here trips that assertion.

I think it's more valuable to be properly vetting property cache hits than to allow this resolver test to run. Can we back out the addition of js/src/jit-test/tests/basic/bug633890.js?
Or perhaps the fix is to extend jit_tests.py to cope with tests that are expected to trip an assertion.
Slippery slope!  :-)

(Note browser would have to skip regardless since it uses a single browser instance, not one per test.)
(In reply to comment #24)
> Slippery slope!  :-)

Well, okay: The test should be deleted, as it's checking something that we don't support yet. :)
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.

Attachment

General

Created:
Updated:
Size: