Closed
Bug 624547
Opened 14 years ago
Closed 14 years ago
Assertion failure: LIR type error (start of writer pipeline): arg 1 of 'eqi' is 'i2d' which has type double (expected int): 0
Categories
(Core :: JavaScript Engine, defect, P1)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
mozilla2.0b10
Tracking | Status | |
---|---|---|
blocking2.0 | --- | betaN+ |
People
(Reporter: jandem, Assigned: brendan)
Details
(Whiteboard: [sg:nse][hardblocker] fixed-in-tracemonkey)
Attachments
(1 file, 1 obsolete file)
2.18 KB,
patch
|
brendan
:
review+
|
Details | Diff | Splinter Review |
Testcase:
---
function f(x) {
delete arguments[0];
for(var i=0; i<20; i++) {
arguments[0] !== undefined;
}
}
f(1);
---
Assertion failure: LIR type error (start of writer pipeline): arg 1 of 'eqi' is 'i2d' which has type double (expected int): 0 (../nanojit/LIR.cpp:3207)
Bus error
This is almost the same test case as in bug 621022, but the loop is now inside the function, after the delete.
Updated•14 years ago
|
Assignee: general → jwalden+bmo
Comment 1•14 years ago
|
||
I'm eyeballing this as reading a magic value from the arguments object, and I am predicting on the basis of almost no evidence whatsoever that it's a crash but not a worrisome, security-critical one, so I'll swing back to this after blockers finish. If someone not busy wants to spend time investigating to determine otherwise, I'm more than happy to fix sooner.
Assignee | ||
Comment 2•14 years ago
|
||
Nick may have a fast fix.
/be
![]() |
||
Comment 3•14 years ago
|
||
I took a look but can't see a fast fix. Here's the bad LIR:
00015: 4 argsub 0
------------------------------ # JSOP_ARGSUB
ldi2 = ldi.sp sp[-32]
$stack2 = i2d ldi2
sti.sp sp[0] = ldi2
00018: 4 getgname "undefined"
------------------------------ # JSOP_GETGNAME
globalObj = immi 0xf6d02028
sti.sp sp[8] = strict/*0*/
00021: 4 strictne
------------------------------ # JSOP_STRICTNE
eqi2 = eqi $stack2, strict/*0*/ ### TYPE ERROR
eqi3 = eqi eqi2, strict/*0*/
sti.sp sp[0] = eqi3
The problem seems to be with record_JSOP_ARGSUB(). In particular, we end up in a branch in importImpl that looks like this:
if (t == JSVAL_TYPE_INT32) { /* demoted */
JS_ASSERT(hasInt32Repr(*(const Value *)p));
/*
* Ok, we have a valid demotion attempt pending, so insert an integer
* read and promote it to double since all arithmetic operations expect
* to see doubles on entry. The first op to use this slot will emit a
* d2i cast which will cancel out the i2d we insert here.
*/
ins = w.ldi(addr);
ins = w.i2d(ins);
Maybe that d2i cast isn't being performed? Not sure. Then again, it's surprising that 't' is JSVAL_TYPE_INT32 here, seems like it should be JSVAL_TYPE_UNDEFINED. So maybe the importTypeMap[] still thinks that arguments[0] is an integer, ie. it hasn't been updated for the delete?
Assignee | ||
Comment 4•14 years ago
|
||
> the importTypeMap[] still thinks that arguments[0] is an integer, ie. it hasn't
> been updated for the delete?
Ding ding ding...
/be
Ah, it's not that the importTypeMap must be filled, but that the tracer is missing a set() somewhere. Anyway, we should just abort when deleting arguments.
Assignee | ||
Comment 6•14 years ago
|
||
(In reply to comment #5)
> Ah, it's not that the importTypeMap must be filled, but that the tracer is
> missing a set() somewhere. Anyway, we should just abort when deleting
> arguments.
The loop is after the delete. We're not recording when it executes.
/be
Ah, sorry, read too quickly. We still don't want to touch importTypeMap. We want to abort in ARGSUB. ARGSUB is probably missing a guard too.
Assignee | ||
Comment 8•14 years ago
|
||
Good call on ARGSUB -- of course we don't want to abort it always, only if the frame already has an arguments object and the slot in question was deleted.
/be
Assignee | ||
Updated•14 years ago
|
blocking2.0: --- → ?
OS: Mac OS X → All
Priority: -- → P1
Hardware: x86 → All
Target Milestone: --- → mozilla2.0b10
Assignee | ||
Comment 9•14 years ago
|
||
(In reply to comment #8)
> Created attachment 502757 [details] [diff] [review]
> proposed fix
>
> Good call on ARGSUB -- of course we don't want to abort it always,
which you knew, cuz you pointed out the need to guard ;-). Mental tracing page-in complete.
/be
Assignee | ||
Comment 10•14 years ago
|
||
Comment on attachment 502757 [details] [diff] [review]
proposed fix
Argh, this isn't guarding what's tested. We need to guard that there isn't an arguments object for the entry frame at trace trigger time. I don't see any protection against recording without an arguments object but triggering with. Will try to write a testcase.
The guardNotHole helper assumes as arguments object, so it will NPE here if we don't have one.
/be
Attachment #502757 -
Attachment is obsolete: true
Attachment #502757 -
Flags: review?(dvander)
(In reply to comment #10)
> arguments object for the entry frame at trace trigger time. I don't see any
> protection against recording without an arguments object but triggering with.
argsobj is part of the entry typemap, so you're good - we'd build a new trace.
re: the patch, I would suggest putting the argsobj condition inside the main if, and using that to (1) abort the trace if there's a hole, and (2) guard that there's no hole.
Updated•14 years ago
|
blocking2.0: ? → betaN+
Whiteboard: hardblocker
Assignee | ||
Comment 12•14 years ago
|
||
(In reply to comment #11)
> (In reply to comment #10)
> > arguments object for the entry frame at trace trigger time. I don't see any
> > protection against recording without an arguments object but triggering with.
>
> argsobj is part of the entry typemap, so you're good - we'd build a new trace.
Oh good -- but in that case:
> re: the patch, I would suggest putting the argsobj condition inside the main
> if, and using that to (1) abort the trace if there's a hole, and (2) guard that
> there's no hole.
Don't need any of that if we insist on null argsobj, indeed can't guard on hole without a non-null argsobj (comment 10 last para). Right?
/be
Comment on attachment 502757 [details] [diff] [review]
proposed fix
>- if (!fp->fun()->isHeavyweight()) {
>+ if (!fp->hasArgsObj() && !fp->fun()->isHeavyweight()) {
> uintN slot = GET_ARGNO(cx->regs->pc);
> if (slot >= fp->numActualArgs())
> RETURN_STOP_A("can't trace out-of-range arguments");
>+
>+ LIns *a_ins = getFrameObjPtr(fp->addressOfArgs());
>+ guardNotHole(a_ins, w.nameImmui(slot));
>+
r=me with the guard gone, Brendan says it's okay to abort on ARGSUB w/ argsobj in play.
Attachment #502757 -
Flags: review+
![]() |
||
Updated•14 years ago
|
Attachment #502757 -
Attachment is obsolete: false
Assignee | ||
Comment 14•14 years ago
|
||
Attachment #502757 -
Attachment is obsolete: true
Attachment #502940 -
Flags: review+
Assignee | ||
Comment 15•14 years ago
|
||
Whiteboard: hardblocker → hardblocker, fixed-in-tracemonkey
Comment 16•14 years ago
|
||
(In reply to comment #1)
> I'm eyeballing this as reading a magic value from the arguments object, and I
> am predicting on the basis of almost no evidence whatsoever that it's a crash
> but not a worrisome, security-critical one,
After figuring out the problem and patch did this turn out to be true?
Whiteboard: hardblocker, fixed-in-tracemonkey → [sg:needinfo][hardblocker] fixed-in-tracemonkey
Comment 17•14 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Comment 19•14 years ago
|
||
Ping?
(In reply to comment #16)
> After figuring out the problem and patch did this turn out to be [not actually a security problem]?
![]() |
||
Comment 20•14 years ago
|
||
(In reply to comment #16)
>
> After figuring out the problem and patch did this turn out to be true?
I don't have a good sense on this particular bug, but LIR type errors are usually considered security problems because the results are... unpredictable. So, in the absence of other information I'd say it was a security problem.
In this case it's safe because at worst we'll box a hole as an object, so it's a near-NULL crash.
Updated•14 years ago
|
Group: core-security
Whiteboard: [sg:needinfo][hardblocker] fixed-in-tracemonkey → [sg:nse][hardblocker] fixed-in-tracemonkey
You need to log in
before you can comment on or make changes to this bug.
Description
•