Last Comment Bug 338288 - Firefox crashes [@ nsQueryInterfaceWithError::operator()] or allows loading custom code into chrome windows on replacing a frameset containing a frame that had delayed server response
: Firefox crashes [@ nsQueryInterfaceWithError::operator()] or allows loading c...
Status: RESOLVED FIXED
[sg:critical][patch] w/PoC
: crash, fixed1.8.1, regression, verified1.8.0.5
Product: Core
Classification: Components
Component: DOM (show other bugs)
: Trunk
: All All
: P1 critical (vote)
: mozilla1.9alpha1
Assigned To: Blake Kaplan (:mrbkap)
: Hixie (not reading bugmail)
Mentors:
http://wargers.org/mozilla/bug338288/
Depends on:
Blocks: sbb? 304882
  Show dependency treegraph
 
Reported: 2006-05-17 05:53 PDT by tgirmann
Modified: 2007-08-22 14:52 PDT (History)
10 users (show)
dveditz: blocking1.8.0.5+
dveditz: in‑testsuite?
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Test suite for this bug - install on a perl enabled web server (4.57 KB, application/zip)
2006-05-17 05:55 PDT, tgirmann
no flags Details
A simple exploit based on this bug, this time faking a master password dialog (7.44 KB, application/zip)
2006-06-07 09:16 PDT, tgirmann
no flags Details
backtrace from debug build (17.68 KB, text/plain)
2006-06-12 16:20 PDT, Martijn Wargers [:mwargers] (not working for Mozilla)
no flags Details
reduced testcase using iframe (1006 bytes, text/html)
2006-06-16 01:40 PDT, moz_bug_r_a4
no flags Details
reduced testcase using window.open() (997 bytes, text/html)
2006-06-16 01:41 PDT, moz_bug_r_a4
no flags Details
Proof of concept for code injection (2.67 KB, text/html)
2006-06-16 15:12 PDT, tgirmann
no flags Details
Proposed fix (9.55 KB, patch)
2006-06-20 11:17 PDT, Blake Kaplan (:mrbkap)
jst: review+
bzbarsky: superreview+
dveditz: approval1.8.0.5+
mconnor: approval1.8.1+
Details | Diff | Splinter Review
history test case (2.66 KB, text/html)
2006-07-27 01:00 PDT, tgirmann
no flags Details

Description tgirmann 2006-05-17 05:53:44 PDT
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3

This suite loads a frameset that contains a frameset which in turn contains a frame, launches a popup that keeps a reference to one of its elements, submits the innermost frame (to the delay perl script) and then replaces the inner frameset two times. For an unknown reason the old frame remains accessible from the popup window in a zombie state, it is possible to load web pages into it (the firefox status bar reflects that the page and its media are being loaded although nothing else is visible).

Even more weird, when launching a popup dialog from that frame, previously launched popup windows get overwritten - including chrome windows (e.g. browser properties).

Sometimes the browser also crashes while doing this due to an attempt to dereference a function pointer on a freed object. Here this should just crash the browser; although it seems to be impossible to me right now there might be the chance of executing arbitrary code that way.


Reproducible: Always

Steps to Reproduce:
1. Unzip the contained files onto some web server (there's a perl file that is required for creating a delay of 2 seconds).
2. Open index.html
3. Follow instructions

Actual Results:  
Browser crashes or loads a custom html page into a chrome window

Expected Results:  
Browser should have prevented javascript code from performing those actions
Comment 1 tgirmann 2006-05-17 05:55:30 PDT
Created attachment 222338 [details]
Test suite for this bug - install on a perl enabled web server
Comment 2 Martijn Wargers [:mwargers] (not working for Mozilla) 2006-05-17 07:25:24 PDT
I've put the testsuite here, for easier testing:
http://wargers.org/mozilla/bug338288/
(instead of perl I used php here)
I've password protected it: username: frame , password: frame

Talkback ID with current trunk build: TB18791374M
nsQueryInterfaceWithError::operator()   nsCOMPtr<nsIWebNavigation>::nsCOMPtr<nsIWebNavigation>   nsLocation::GetHref   XPTC_InvokeByIndex   XPCWrappedNative::CallMethod  

I don't crash in Mozilla1.7, so this is a regression.
Comment 3 tgirmann 2006-05-17 07:54:01 PDT
(In reply to comment #2)

That test suite does not always work (probably only when using good connection and/or sites are already cached). After hitting the URL do nothing for 10 seconds, if the popup window closes itself something went wrong and it didn't work, it might work if you try again.
Comment 4 tgirmann 2006-06-05 23:50:38 PDT
I think it's time to fix this possibly dangerous bug, it is still present in Firefox 1.5.0.4
Comment 5 tgirmann 2006-06-07 09:16:16 PDT
Created attachment 224707 [details]
A simple exploit based on this bug, this time faking a master password dialog

It works like the previous test case: put onto perl enabled web space (required for the delay script), start index.html, click the button and wait about 10 seconds...

Things are delayed for easier development but could be done faster of course.
Comment 6 Martijn Wargers [:mwargers] (not working for Mozilla) 2006-06-12 16:20:13 PDT
Created attachment 225344 [details]
backtrace from debug build

This is a backtrace from my debug build. It crashes as soon as the popup window gets opened.

Program received signal SIGSEGV, Segmentation fault.
0x6f208660 in JS_GetOptions (cx=0x0) at c:/mozilla/mozilla/js/src/jsapi.c:1049
warning: Source file is more recent than executable.

---Type <return> to continue, or q <return> to quit---
1049        return cx->options;
(gdb) bt
#0  0x6f208660 in JS_GetOptions (cx=0x0)
    at c:/mozilla/mozilla/js/src/jsapi.c:1049
#1  0x05127872 in GetScriptContextFromJSContext(JSContext*) (cx=0x0)
    at ../../../dist/include/dom/nsIScriptContext.h:365
#2  0x04f8a94f in nsJSUtils::GetDynamicScriptContext(JSContext*) (
    aContext=0x0) at c:/mozilla/mozilla/dom/src/base/nsJSUtils.cpp:216
#3  0x04d44003 in IsContextOnStack(nsIJSContextStack*, JSContext*) (
    aStack=0xb98288, aContext=0xef262f8)
    at c:/mozilla/mozilla/content/base/src/nsContentUtils.cpp:2250
#4  0x04d442bc in nsCxPusher::Push(nsISupports*) (this=0x22a2d0,
    aCurrentTarget=0xf2c07c8)
    at c:/mozilla/mozilla/content/base/src/nsContentUtils.cpp:2302
etc.
Comment 7 Martijn Wargers [:mwargers] (not working for Mozilla) 2006-06-12 17:47:15 PDT
This regressed between 2005-08-22 and 2005-08-23:
http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&module=all&branch=HEAD&branchtype=match&dir=&file=&filetype=match&who=&whotype=match&sortby=Date&hours=2&date=explicit&mindate=2005-08-22+07&maxdate=2005-08-23+09&cvsroot=%2Fcvsroot
In 2005-08-22 the popup window closes like it is supposed to do (I think).
In 2005-08-23 not anymore and opening the options window causes a crash.
This is a bad bug, cc-ing some people who want/might be able to fix this bug.

It it's needed, I could try and minimise the testcase further.
Comment 8 Blake Kaplan (:mrbkap) 2006-06-12 17:55:36 PDT
That last stack looks a lot like bug 340602... The crash in operator() is something else entirely, however.
Comment 9 Boris Zbarsky [:bz] 2006-06-12 22:44:23 PDT
hmm... in a build with the patch for bug 340602 in it I don't seem to crash....  Martijn, I assume you're still crashing with such a build?
Comment 10 Martijn Wargers [:mwargers] (not working for Mozilla) 2006-06-13 00:56:37 PDT
Yes, I still crash with a 2006-06-12 trunk build.
What happens when you open the Options/Preferences window while the popup window is open (let the popup window open a few seconds before you open the Options/Preferences window)?
I've seen it happening once (when it didn't crash) that it gets replaced by a window from the user (but still with chrome privileges).
Comment 11 tgirmann 2006-06-13 04:58:00 PDT
(In reply to comment #10)
> What happens when you open the Options/Preferences window while the popup
> window is open (let the popup window open a few seconds before you open the
> Options/Preferences window)?
> I've seen it happening once (when it didn't crash) that it gets replaced by a
> window from the user (but still with chrome privileges).
> 

This is what the first attachment is expected to do (works most of the time on my computer). Did you try the second test case (224707)? IMO it should work better and crash less often.
Comment 12 Daniel Veditz [:dveditz] 2006-06-13 14:35:09 PDT
In Firefox 1.5.0.4 the pref dialog gets replaced by user code. The the window is still a ChromeWindow, but the code appears to have normal user privilege. But given the chrom window thing we can probably play __parent__ tricks to re-elevate privilege.

Martijn, in comment 10 are you saying on the trunk that window has chrome privs already? Why the difference
Comment 13 Martijn Wargers [:mwargers] (not working for Mozilla) 2006-06-13 14:39:38 PDT
(In reply to comment #12)
> Martijn, in comment 10 are you saying on the trunk that window has chrome privs
> already? Why the difference

Sorry, I haven't tested that, I assumed that it had chrome privs.

Comment 14 moz_bug_r_a4 2006-06-16 01:38:31 PDT
It seems that the location object's mDocShell is not nulled out even though it
should be, and ends up being a dangling pointer.  Is this a regression from Bug
304882?

I'm attaching two reduced testcases, which are iframe version and window.open()
version.  On Windows XP, I can reproduce with both testcases, "Page Info"
window gets replaced by user code.  On Linux, I can reproduce with iframe
version testcase, crashes.

When "Page Info" window got replaced by user code, the window no longer has
chrome privs (also on the trunk).  And I cannot see a way to elevate privilege
using __parent__ tricks.  Even when the location object points to the chrome
window (chrome://browser/content/pageInfo.xul), the location object itself is
not a privileged object, its __parent__ is the content window that has been
already closed.  But, the user code can get the "Page Info" window's opener
that is a browser window.  This could be abused somehow, but I don't have any
idea for now.
Comment 15 moz_bug_r_a4 2006-06-16 01:40:49 PDT
Created attachment 225845 [details]
reduced testcase using iframe
Comment 16 moz_bug_r_a4 2006-06-16 01:41:54 PDT
Created attachment 225846 [details]
reduced testcase using window.open()
Comment 17 tgirmann 2006-06-16 15:08:45 PDT
I've spent some time examining this bug further using moz_bug_r_a4@yahoo.com's test cases (thanks alot for simplying it). Using the location object alone can cause limited damage only - it is possible to create another window and spy (or manipulate) on the urls the user is accessing, doing other things (such as injecting javascript:-urls) seems to be impossible.

However, by letting it crash in a controlled way, it's possible to inject custom code. I'll attach an example demonstrating that.
Comment 18 tgirmann 2006-06-16 15:12:40 PDT
Created attachment 225924 [details]
Proof of concept for code injection

This example uses JavaScript commands to flood the memory with strings containing ASM code and hopefully also fill what was freed but is still pointed to by the location object.
Works on windows only (should not rely on OS details) but requires Firefox 1.8.0.4: 2006050817 (probably German version only).
Comment 19 Boris Zbarsky [:bz] 2006-06-19 20:13:39 PDT
Yeah, this looks very likely to be a regression from bug 304882.  How _is_ the docshell supposed to be nulled out now in mLocation, in general?
Comment 20 moz_bug_r_a4 2006-06-20 08:43:02 PDT
(In reply to comment #19)

1) A current document's mLocation.mDocShell is nulled out when a window is
   being destroyed.
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/docshell/base/nsDocShell.cpp&rev=1.799&mark=3611-3612#3611
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/dom/src/base/nsGlobalWindow.cpp&rev=1.859&mark=1624-1625#1624

2) If an old document's presentation has been cached in session history, its
   mLocation.mDocShell is nulled out in WindowStateHolder dtor.
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/dom/src/base/nsGlobalWindow.cpp&rev=1.859&mark=1005-1008#986

With the testcases in this bug, the old document's presentation is not cached
in session history. (when an old document is "about:blank" or is in subframe,
bfcache is not used.) Thus, WindowStateHolder for that document is not created,
and mLocation.mDocShell is left alone.
Comment 21 Blake Kaplan (:mrbkap) 2006-06-20 11:17:04 PDT
Created attachment 226355 [details] [diff] [review]
Proposed fix

The trick here is that loading a new document in a window causes SetNewDocument to clear the outer window's mLocation. We can't invalidate the docshell then, since doing so would regress bug 304882 (so this is a regression from that bug). Therefore, the window will be unable to update the docshell on any lingering references to the location object, and if the docshell goes away, the location objects will happily continue using their deleted pointers.
Comment 22 Johnny Stenback (:jst, jst@mozilla.com) 2006-06-20 11:47:59 PDT
Comment on attachment 226355 [details] [diff] [review]
Proposed fix

r=jst
Comment 23 Blake Kaplan (:mrbkap) 2006-06-20 11:57:31 PDT
Fix checked into trunk.
Comment 24 Daniel Veditz [:dveditz] 2006-06-20 14:14:51 PDT
(In reply to comment #18)
> Works on windows only (should not rely on OS details) but requires Firefox
> 1.8.0.4: 2006050817 (probably German version only).

Exploit works just fine on an English version -- file created on my C:\ drive.
Comment 25 Daniel Veditz [:dveditz] 2006-06-20 14:18:52 PDT
Comment on attachment 226355 [details] [diff] [review]
Proposed fix

approved for 1.8.0 branch, a=dveditz for drivers
Comment 26 Blake Kaplan (:mrbkap) 2006-06-21 10:59:55 PDT
Fix checked into the 1.8.0 branch.
Comment 27 Blake Kaplan (:mrbkap) 2006-06-22 15:20:11 PDT
Checked into the 1.8 branch.
Comment 28 tgirmann 2006-06-25 23:35:28 PDT
Good work. The bug seems to be gone in the nightly build in all test cases (including the web application which originally exhibited this bug).
Comment 29 Jay Patel [:jay] 2006-06-26 16:15:36 PDT
v.fixed on 1.8.0 branch with Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US;
rv:1.8.0.5) Gecko/20060626 Firefox/1.5.0.5, no exploits from any testcases and per  reporter's testing noted in comment #28.
Comment 30 tgirmann 2006-07-27 01:00:04 PDT
Created attachment 230858 [details]
history test case

Might or might not be related to this: I've played around with the test cases again and noticed that when using the history instead the following error is appended to the javascript console:

Fehler: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHistory.back]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: file:///C:/test/test.html :: c :: line 86"  data: no]

This happens both in Firefox 1.5.0.4 and Firefox 1.5.0.5. Sorry for reporting it now as Firefox 1.5.0.5 has already been released but I didn't notice that before. Can someone please take a look and check what's going on and whether or not this is a real problem?
Comment 31 Blake Kaplan (:mrbkap) 2006-07-27 16:26:36 PDT
(In reply to comment #30)
> Can someone please take a look and check what's going on and whether or
> not this is a real problem?

This is the expected behavior (and what should be the behavior of the original testcase without the frames[0].location.href = 'about:blank').

I don't believe there's a potential exploit lurking here since we never have a case where the history object's only ref is from JS (the window holds onto it until it is closed), so the window can always null out the history object's docshell at the proper time.
Comment 32 Alexander Sack 2006-07-28 06:38:24 PDT
So do some parts of this bug apply to aviary as well or is everything in here a regression not in aviary? At least, I can't get those testcases to work.

Note You need to log in before you can comment on or make changes to this bug.