Closed Bug 422286 Opened 16 years ago Closed 16 years ago

array_slice reads arbitrary memory when array's length is assigned

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

VERIFIED FIXED
mozilla1.9beta5

People

(Reporter: dbaron, Assigned: shaver)

References

Details

Attachments

(1 file, 1 obsolete file)

I was about to write this as a comment in bug 419695, but I realized I should probably file it as a separate security bug:

This is a JS engine bug in array_slice.

In particular, we're calling array_slice on an array with:

ARRAY_DENSE_LENGTH(obj) == 48
array->fslots[JSSLOT_ARRAY_COUNT] == 44
array->fslots[JSSLOT_ARRAY_LENGTH] == 164 (the .length property)

and we happily copy 164 bytes.

This is easily reproducable in xpcshell with:
var a = [];
a.length = 10000000;
a.slice(1);
Actually, maybe this isn't so bad.  I was thinking it was a way to read arbitrary memory, but you really only have that arbitrary memory in jsvals, which are only going to be readable without crashing 5/8 of the time (low bit 1, or 3 lowest bits 0x6), so it's probably not too useful.

I *think* it's also trunk only.
That DENSE_LENGTH stuff is all trunk-only.  Taking, patch tonight.
Assignee: general → shaver
We could optimize this in a couple of ways, but I don't think it's worth it.

r? to crowder, but I'll take a + from any JS hacker who's around.

Test fodder:

Array(10000).slice(1)
a = Array(1); a.length = 10000; a.slice(1);
a = Array(1); a.length = 10000; a.slice(-1);
Attachment #308788 - Flags: review?(crowder)
Attachment #308788 - Flags: approval1.9?
Adding some review possibles.
Isn't end == ARRAY_DENSE_LENGTH(obj) ok?

Also, doesn't this whole thing initialize nobj->fslots[JSSLOT_ARRAY_COUNT] incorrectly, since it assumes that everything in obj->dslots is not JSVAL_HOLE ?
(In reply to comment #5)
> Isn't end == ARRAY_DENSE_LENGTH(obj) ok?

No: DENSE_LENGTH, like LENGTH, counts one more than the highest available slot.

> Also, doesn't this whole thing initialize nobj->fslots[JSSLOT_ARRAY_COUNT]
> incorrectly, since it assumes that everything in obj->dslots is not JSVAL_HOLE
> ?

Yeah, it does, as does the JSOP_NEWARRAY patch elsewhere, and a few other such optimizations.  I want to write more tests for that before attacking them, so I'd rather leave it to another patch; it's not as high a priority as this crash/sec fix.

(In reply to comment #6)
> (In reply to comment #5)
> > Isn't end == ARRAY_DENSE_LENGTH(obj) ok?
> 
> No: DENSE_LENGTH, like LENGTH, counts one more than the highest available slot.

Yeah, but end is a fencepost too, not a fence rail. Dbaron's point was, I bet, that the test should use <=, not <.

/be
(In reply to comment #7)
> (In reply to comment #6)
> > (In reply to comment #5)
> > > Isn't end == ARRAY_DENSE_LENGTH(obj) ok?
> > 
> > No: DENSE_LENGTH, like LENGTH, counts one more than the highest available slot.
> 
> Yeah, but end is a fencepost too, not a fence rail. Dbaron's point was, I bet,
> that the test should use <=, not <.

Curses, and apologies!  New patch inc.
Brendan gets the r?, since he's around!
Attachment #308788 - Attachment is obsolete: true
Attachment #308791 - Flags: review?(brendan)
Attachment #308791 - Flags: approval1.9?
Attachment #308788 - Flags: review?(crowder)
Attachment #308788 - Flags: approval1.9?
Comment on attachment 308791 [details] [diff] [review]
As above, but take fast path all the way up to DENSE_LENGTH

Shaver asked me to review to get this in pronto.
Attachment #308791 - Flags: review?(brendan) → review+
Attachment #308791 - Flags: approval1.9? → approval1.9+
(In reply to comment #6)
> > Also, doesn't this whole thing initialize nobj->fslots[JSSLOT_ARRAY_COUNT]
> > incorrectly, since it assumes that everything in obj->dslots is not JSVAL_HOLE
> > ?
> 
> Yeah, it does, as does the JSOP_NEWARRAY patch elsewhere,

(which one, mine?)

> and a few other such
> optimizations.  I want to write more tests for that before attacking them, so
> I'd rather leave it to another patch; it's not as high a priority as this
> crash/sec fix.

Followup bug on file?

Sorry I was offline a bit, patch looks good to me too.

/be
Fixed, vlad's watching the tree in case we were depending on that lack of memory safety or something.

/cvsroot/mozilla/js/src/jsarray.c,v  <--  jsarray.c
new revision: 3.169; previous revision: 3.168
done
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → FIXED
Follow-up hole-audit bug is 422333, fwiw.
dbaron: I don't think this is sensitive, since it's trunk-only.  OK with opening it?
Target Milestone: --- → mozilla1.9beta5
Yep.  I was going to ask you the same thing...
Group: security
Attachment #308788 - Flags: review+
verified linux|mac|windows

/cvsroot/mozilla/js/tests/js1_5/Array/regress-422286.js,v  <--  regress-422286.js
initial revision: 1.1
Status: RESOLVED → VERIFIED
Flags: in-testsuite+
Flags: in-litmus-
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: