Closed Bug 338288 Opened 18 years ago Closed 18 years ago

Firefox crashes [@ nsQueryInterfaceWithError::operator()] or allows loading custom code into chrome windows on replacing a frameset containing a frame that had delayed server response

Categories

(Core :: DOM: Core & HTML, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.9alpha1

People

(Reporter: tgirmann, Assigned: mrbkap)

References

()

Details

(4 keywords, Whiteboard: [sg:critical][patch] w/PoC)

Crash Data

Attachments

(8 files)

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
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.
Assignee: nobody → general
Status: UNCONFIRMED → NEW
Component: Security → DOM
Ever confirmed: true
Keywords: crash, regression
Product: Firefox → Core
QA Contact: firefox → ian
Summary: Firefox crashes 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 custom code into chrome windows on replacing a frameset containing a frame that had delayed server response
Version: unspecified → Trunk
(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.
Blocks: sbb?
I think it's time to fix this possibly dangerous bug, it is still present in Firefox 1.5.0.4
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.
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.
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.
Flags: blocking1.8.0.5?
That last stack looks a lot like bug 340602... The crash in operator() is something else entirely, however.
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?
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).
(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.
Flags: blocking1.8.0.5? → blocking1.8.0.5+
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
Assignee: general → mrbkap
(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.

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.
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.
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).
Whiteboard: [sg:critical] w/PoC
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?
Blocks: 304882
(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.
Attached patch Proposed fixSplinter Review
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.
Attachment #226355 - Flags: superreview?(bzbarsky)
Attachment #226355 - Flags: review?(jst)
Status: NEW → ASSIGNED
OS: Windows XP → All
Priority: -- → P1
Hardware: PC → All
Whiteboard: [sg:critical] w/PoC → [sg:critical][patch] w/PoC
Target Milestone: --- → mozilla1.9alpha
Attachment #226355 - Flags: superreview?(bzbarsky) → superreview+
Comment on attachment 226355 [details] [diff] [review]
Proposed fix

r=jst
Attachment #226355 - Flags: review?(jst) → review+
Fix checked into trunk.
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Attachment #226355 - Flags: approval1.8.1?
Attachment #226355 - Flags: approval1.8.0.5?
(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 on attachment 226355 [details] [diff] [review]
Proposed fix

approved for 1.8.0 branch, a=dveditz for drivers
Attachment #226355 - Flags: approval1.8.0.5? → approval1.8.0.5+
Fix checked into the 1.8.0 branch.
Keywords: fixed1.8.0.5
Attachment #226355 - Flags: approval1.8.1? → approval1.8.1+
Checked into the 1.8 branch.
Keywords: fixed1.8.1
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).
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.
Attached file 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?
(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.
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.
Group: security
Flags: in-testsuite?
Crash Signature: [@ nsQueryInterfaceWithError::operator()]
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: