Closed Bug 311792 Opened 19 years ago Closed 19 years ago

Unrooted access in Array.prototype methods

Categories

(Core :: JavaScript Engine, defect, P1)

x86
Linux
defect

Tracking

()

VERIFIED FIXED
mozilla1.8rc1

People

(Reporter: igor, Assigned: igor)

References

Details

(Keywords: js1.6, verified1.7.13, verified1.8, Whiteboard: [sg:critical] arbitrary code execution (see comment 8))

Attachments

(3 files, 2 obsolete files)

Here is unrooted object access found in Array.prototype implementation in jsarray.c 1. array_slice does not root the array for slice results with trivial demonstration of segmentation fault in jsshell: function index_getter() { gc(); return 100; } var a = [0, 1]; a.__defineGetter__(0, index_getter); uneval(a.slice(0, 1)); To make this to crash the browser just replace "gc();" by for (var i = 0; i != 1 << 15; ++i) new Object(); 2. array_reverse does not root v and v2 indexes that it use to hold reversing values. Here is an example for jsshell that demonstrates how to expose 64 bits that holds JSString value into a script variable: var subverted = 0; function index_getter() { delete a[0]; gc(); for (var i = 0; i != 1 << 14; ++i) { var tmp = new String("test"); tmp = null; } return 1; } function index_setter(value) { subverted = value; } var a = [ Math.sqrt(2), 0 ]; a.__defineGetter__(1, index_getter); a.__defineSetter__(1, index_setter); a.reverse(); print(subverted) On my Linux box it prints 1.3303688272434068e-266 which is assembled from JSString bits for 'new String("test");' interpreted as double value. In a similar way one can make a GC thing that JS considers to be JSString from arbitrary double value which could potentially allow to read arbitrary memory context into scripts variables via this pseudo-string. Due to this potential exposure I mark this bug as security-restricted.
Attached patch Fix (obsolete) (deleted) — Splinter Review
I am not 100% sure that I can use argv[argc] as a space for the second local root in array_reverse. Is it OK?
Attachment #199011 - Flags: review?(brendan)
Attached patch Fix 2 (obsolete) (deleted) — Splinter Review
The previois fix should move, not copy the line with *rval = OBJECT_TO_JSVAL(nobj) to the beginning of the function. So here is removal of the extra assignment.
Attachment #199011 - Attachment is obsolete: true
Attachment #199013 - Flags: review?(brendan)
Attachment #199011 - Flags: review?(brendan)
Thanks, Igor. Another old bug that can be safely fixed for 1.8. mrbkap, can you drive this one in? /be
Flags: blocking1.8rc1+
Keywords: js1.6
Comment on attachment 199013 [details] [diff] [review] Fix 2 To use argv[argc] as a local root, you need to reserve one local root by changing {"reverse", array_reverse, 0,JSFUN_GENERIC_NATIVE,0}, to have 1 instead of 0 in the last member initializer. /be
Attached patch Fix 3 (deleted) — Splinter Review
I used 2 extra local roots to swap temporaries for less hackish code and added that 2 into array_methods declaration. More hackish version would use argv[-2] for the second local root, right?
Attachment #199013 - Attachment is obsolete: true
Attachment #199024 - Flags: review?(brendan)
Attachment #199013 - Flags: review?(brendan)
Comment on attachment 199024 [details] [diff] [review] Fix 3 Great, thanks. I will rely on mrbkap to do a second review and help get this checked in. /be
Attachment #199024 - Flags: review?(mrbkap)
Attachment #199024 - Flags: review?(brendan)
Attachment #199024 - Flags: review+
Attachment #199024 - Flags: approval1.8rc1+
Attachment #199024 - Flags: approval1.7.13+
Attachment #199024 - Flags: approval-aviary1.0.8+
Flags: blocking1.7.13+
Flags: blocking-aviary1.0.8+
Comment on attachment 199024 [details] [diff] [review] Fix 3 r=mrbkap
Attachment #199024 - Flags: review?(mrbkap) → review+
Whiteboard: [sg:low] memory read at least, more?
> [sg:low] memory read at least, maybe more Unfortunately it is the same type of problem as in bug 311497 and can be used for arbitrary code execution, see comment 10 there for details.
Whiteboard: [sg:low] memory read at least, more? → [sg:critical] arbitrary code execution (see comment 8)
Blake, would you shepherd this to fixed resolution? Thanks, /be
Assignee: general → mrbkap
Fix checked into trunk.
Status: NEW → RESOLVED
Closed: 19 years ago
Priority: -- → P1
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.8rc1
Blocks: sbb?
(In reply to comment #5) > Created an attachment (id=199024) [edit] > Fix 3 > > I used 2 extra local roots to swap temporaries for less hackish code and added > that 2 into array_methods declaration. > > More hackish version would use argv[-2] for the second local root, right? That would be the callee function object, but it might be bad to overwrite it, if you use an in-runtime debugger that might be confused. /be
Priority: P1 → --
Target Milestone: mozilla1.8rc1 → ---
Fix checked into MOZILLA_1_8_BRANCH. Reopening to give to Igor.
Status: RESOLVED → REOPENED
Keywords: fixed1.8
Priority: -- → P1
Resolution: FIXED → ---
Target Milestone: --- → mozilla1.8rc1
Assignee: mrbkap → igor.bukanov
Status: REOPENED → NEW
Status: NEW → RESOLVED
Closed: 19 years ago19 years ago
Resolution: --- → FIXED
Flags: testcase?
verified firefox 1.5 rc2 linux/win32 2005-11-07
Keywords: fixed1.8verified1.8
testcase+ to get this off my radar. when this is made public, i will check in the test.
Flags: testcase? → testcase+
Fix checked into the 1.7 branches.
js1_5/Array/regress-311792-01.js, js1_5/Array/regress-311792-02.js verified no crash in automatic tests of firefox nightlies 1.7.13, 1.8.0.1, 1.8, 1.9a1 on windows/linux/mac. Note that 1.7.5 and 1.7.12 did crash. For mozilla 1.7.13 on winxp running the tests in the browser_however_ I was able to get a nightly Mozilla 1.7.13 from 20060213 to crash by clicking and attempting to edit the url in the urlbar back and forth from -01 to -02 however it did not crash immediately. I could not reproduce with a debug firefox trunk build from 20060214. I was able to hit an assert in Firefox 1.0.8 debug build from 20060214 though. <http://test.mozilla.com/tests/mozilla.org/js/js-test-driver-standards.html?test=js1_5/Array/regress-311792-01.js;language=language;javascript> Assertion failure: flags != GCF_FINAL, at c:/work/mozilla/builds/ff/1.0.x/mozilla/js/src/jsgc.c:835 + cx 0x03bb08c0 thing 0x03baf368 arg 0x00000000 + vp 0x03c734e8 + flagp 0x03bae225 "" + obj 0x03baeba8 nslots 0x00000005 v 0x80000001 + end 0x03c734e8 + rt 0x00ec9e78 + str 0x03bae9b0 flags 0x10 '' js_MarkGCThing(JSContext * 0x03bb08c0, void * 0x03baf368, void * 0x00000000) line 835 + 35 bytes js_MarkGCThing(JSContext * 0x03bb08c0, void * 0x03bae520, void * 0x00000000) line 919 + 18 bytes js_MarkGCThing(JSContext * 0x03bb08c0, void * 0x03b2a360, void * 0x00000000) line 919 + 18 bytes js_MarkGCThing(JSContext * 0x03bb08c0, void * 0x03b2ad50, void * 0x00000000) line 919 + 18 bytes gc_root_marker(JSDHashTable * 0x00ec9e98, JSDHashEntryHdr * 0x03b8786c, unsigned long 0x000001e6, void * 0x03bb08c0) line 975 + 18 bytes JS_DHashTableEnumerate(JSDHashTable * 0x00ec9e98, int (JSDHashTable *, JSDHashEntryHdr *, unsigned long, void *)* 0x10042cb0 gc_root_marker(JSDHashTable *, JSDHashEntryHdr *, unsigned long, void *), void * 0x03bb08c0) line 618 + 34 bytes js_GC(JSContext * 0x03bb08c0, unsigned int 0x00000000) line 1189 + 21 bytes js_ForceGC(JSContext * 0x03bb08c0, unsigned int 0x00000000) line 1000 + 13 bytes JS_GC(JSContext * 0x03bb08c0) line 1698 + 11 bytes nsJSContext::Notify(nsJSContext * const 0x03bb0720, nsITimer * 0x0344b058) line 1859 + 13 bytes nsTimerImpl::Fire() line 386 nsTimerManager::FireNextIdleTimer(nsTimerManager * const 0x0316f7f0) line 616 nsAppShell::Run(nsAppShell * const 0x02dcd6f8) line 142 nsAppShellService::Run(nsAppShellService * const 0x02dcd638) line 495 xre_main(int 0x00000004, char * * 0x003e6e08, const nsXREAppData * 0x0041e01c kAppData) line 1907 + 35 bytes main(int 0x00000004, char * * 0x003e6e08) line 58 + 18 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 7c816d4f() I think this is fixed, but leaving unverified on the 1.7 branch for now until someone looks at the stack.
Status: RESOLVED → VERIFIED
v ff 1.0.8, 1.5.0.1, 1.5, 1.6a1 20060217 win/linux/mac, mozilla 1.7.13 winxp.
Group: security
RCS file: /cvsroot/mozilla/js/tests/js1_5/GC/regress-311792-01.js,v done Checking in regress-311792-01.js; /cvsroot/mozilla/js/tests/js1_5/GC/regress-311792-01.js,v <-- regress-311792-01.js initial revision: 1.1 done RCS file: /cvsroot/mozilla/js/tests/js1_5/GC/regress-311792-02.js,v done Checking in regress-311792-02.js; /cvsroot/mozilla/js/tests/js1_5/GC/regress-311792-02.js,v <-- regress-311792-02.js initial revision: 1.1 done
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: