Closed
Bug 313763
Opened 19 years ago
Closed 19 years ago
Extra rootless creatures in jsarray.c
Categories
(Core :: JavaScript Engine, defect, P1)
Tracking
()
VERIFIED
FIXED
mozilla1.8rc1
People
(Reporter: igor, Assigned: brendan)
References
Details
(Keywords: js1.6, verified1.7.13, verified1.8, Whiteboard: [sg:critical])
Attachments
(2 files)
2.67 KB,
text/plain
|
Details | |
16.50 KB,
patch
|
igor
:
review+
shaver
:
superreview+
asa
:
approval1.8rc2+
|
Details | Diff | Splinter Review |
Here is another unrooted access bug in jsarray.c.
array_unshift contains the pattern:
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
return JS_FALSE;
if (!IndexToId(cx, last + argc, &id2))
return JS_FALSE;
if (!OBJ_SET_PROPERTY(cx, obj, id2, &v))
return JS_FALSE;
If last + argc exceeds JSVAL_INT_MAX, IndexToId would GC allocate string for the index. Thus if v holds unrooted value after OBJ_GET_PROPERTY and that allocation would trigger GC, then OBJ_SET_PROPERTY would store GC-collected value.
The example bellow demonstrates the bug in jsshell compiled with TOO_MUCH_GC. On my box it gives segmentation fault on the last expected === actual compare operation. The same pattern present in jsarray.c also exists in array_splice, array_concat, array_slice, array_extra, but in this case a bug demo would have to loop through array holes until JSVAL_INT_MAX which would be a log story.
var N = 0x80000002;
var array = Array(N);
array[N - 1] = 1;
array[N - 2] = 2;
// Set getter not to wait untill engine loops through 2^31 holes in the array.
var LOOP_TERMINATOR = "stop_long_loop";
array.__defineGetter__(N - 2, function() {
throw "stop_long_loop";
});
var prepared_string = String(1);
array.__defineGetter__(N - 1, function() {
var tmp = prepared_string;
prepared_string = null;
return tmp;
})
try {
array.unshift(1);
} catch (e) {
if (e !== LOOP_TERMINATOR)
throw e;
}
var expected = "1";
var actual = array[N];
print(expected === actual);
Reporter | ||
Comment 1•19 years ago
|
||
When I was looking at jarray.c for unrooted bugs on previous occasions, I assumed that IndexToId would never call GC so it was seemed OK to use local jsval to hold potentially unrooted jsval before passing it to OBJ_SET_PROPERTY.
Given that I would really suggest to use explicit local roots for all the cases where jsarray.c currently use just plain local C jsval variable.
Severity: normal → critical
Assignee | ||
Comment 2•19 years ago
|
||
Didn't we fix array_reverse already? We are too friend to make consistent changes in all the similar places. I at least have no excuse, since I know that IndexToId can GC. Thanks again, Igor.
/be
Assignee: general → brendan
Flags: blocking1.8rc1+
Keywords: js1.6
Priority: -- → P1
Target Milestone: --- → mozilla1.8rc1
Reporter | ||
Comment 3•19 years ago
|
||
(In reply to comment #2)
> Didn't we fix array_reverse already?
>
Yes, that was fixed. Now I have another question. What exactly roots the results of IndexToId when they are atoms? Just cx->lastAtom or there is another refrence that can not be overwritten by a "smart" getter/setter?
Priority: P1 → --
Target Milestone: mozilla1.8rc1 → ---
Assignee | ||
Comment 4•19 years ago
|
||
(In reply to comment #3)
> Now I have another question. What exactly roots the
> results of IndexToId when they are atoms?
Last-ditch GCs do not collect atoms. See GC_KEEP_ATOMS and JS_{,UN}KEEP_ATOMS.
/be
Status: NEW → ASSIGNED
Comment 5•19 years ago
|
||
At a quick glance the 1.0 branch appears to be safe (the IndexToId happens before the get/set rather than between), but nominating for that branch so we remember to take a closer look.
Flags: blocking1.7.13?
Flags: blocking-aviary1.0.8?
Whiteboard: [sg:critical?]
Comment 6•19 years ago
|
||
Updated•19 years ago
|
Flags: testcase?
Updated•19 years ago
|
Flags: blocking1.8rc1+ → blocking1.8rc1?
Assignee | ||
Comment 7•19 years ago
|
||
Straightforward explicit local rooting, yay.
/be
Attachment #200961 -
Flags: superreview?(shaver)
Attachment #200961 -
Flags: review?(igor.bukanov)
Comment 8•19 years ago
|
||
Comment on attachment 200961 [details] [diff] [review]
proposed fix
sr=shaver. I had to remind myself of how the extra local explicit
roots work, but I'm much better now!
Comment 9•19 years ago
|
||
Comment on attachment 200961 [details] [diff] [review]
proposed fix
sr=shaver, I say!
Attachment #200961 -
Flags: superreview?(shaver) → superreview+
Reporter | ||
Comment 10•19 years ago
|
||
Comment on attachment 200961 [details] [diff] [review]
proposed fix
I would like to check before giving "+" that rval2 from array_extra after js_Invoke just aliases a value that is always stored in GC-scanned area.
Reporter | ||
Comment 11•19 years ago
|
||
Comment on attachment 200961 [details] [diff] [review]
proposed fix
I still not 100% about that rval2 in array_extra - no time to check, but if there is something, it would go to another bug (if ever ;)
Attachment #200961 -
Flags: review?(igor.bukanov) → review+
Comment 12•19 years ago
|
||
rval2 is always sp[-1], yes, and only "leaked" from that loop via the SET_PROPERTY in the MAP case. Safe as can be!
Assignee | ||
Comment 13•19 years ago
|
||
This should ridealong.
/be
Priority: -- → P1
Whiteboard: [sg:critical?] → [sg:critical]
Target Milestone: --- → mozilla1.8rc1
Assignee | ||
Updated•19 years ago
|
Attachment #200961 -
Flags: approval1.8rc1?
Assignee | ||
Comment 14•19 years ago
|
||
Fixed on trunk, riding along for rc2.
/be
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Flags: blocking1.8rc2?
Resolution: --- → FIXED
Comment 15•19 years ago
|
||
moving out to the 1.8 rc2 ride-along candidate list. We'll consider taking this if we do an RC2.
Flags: blocking1.8rc1?
Updated•19 years ago
|
Attachment #200961 -
Flags: approval1.8rc1? → approval1.8rc2+
Assignee | ||
Comment 16•19 years ago
|
||
Hrm, this wasn't checked in on the trunk (I suck). I'll let it bake overnight then hit the 1.8 branch if all looks well (as expected).
/be
Assignee | ||
Comment 17•19 years ago
|
||
Forgot to mark this fixed1.8, but the patch landed here:
http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&module=all&branch=MOZILLA_1_8_BRANCH&branchtype=match&dir=mozilla%2Fjs%2Fsrc&file=jsarray.c&filetype=match&who=&whotype=match&sortby=Date&hours=2&date=week&mindate=&maxdate=+&cvsroot=%2Fcvsroot
/be
Keywords: fixed1.8
Comment 18•19 years ago
|
||
clearing the nomination flag now that this is checked in on the branch and this isn't something internal QA is going to be able to verify.
Flags: blocking1.8rc2?
Comment 19•19 years ago
|
||
verified firefox 1.5 rc2 linux/win32 2005-11-07
Keywords: fixed1.8 → verified1.8
Updated•19 years ago
|
Flags: blocking1.7.13?
Flags: blocking1.7.13+
Flags: blocking-aviary1.0.8?
Flags: blocking-aviary1.0.8+
Comment 20•19 years ago
|
||
testcase+ to get this off my radar. when this is made public, i will check in
the test.
Flags: testcase? → testcase+
Comment 21•19 years ago
|
||
Fix checked into the 1.7 branch as part of the bug 311497 checkin.
Keywords: fixed-aviary1.0.8,
fixed1.7.13
Comment 22•19 years ago
|
||
verified firefox/1.7.13,1.8.0.1,1.8,1.9a1 win/linux/mac, note that 1.7.5/1.7.12 passed the test as well.
Status: RESOLVED → VERIFIED
Keywords: fixed-aviary1.0.8 → verified-aviary1.0.8
Updated•19 years ago
|
Group: security
Comment 24•19 years ago
|
||
RCS file: /cvsroot/mozilla/js/tests/js1_5/GC/regress-313763.js,v
done
Checking in regress-313763.js;
/cvsroot/mozilla/js/tests/js1_5/GC/regress-313763.js,v <-- regress-313763.js
initial revision: 1.1
done
You need to log in
before you can comment on or make changes to this bug.
Description
•