Bug 634986 (CVE-2011-0065)

Use-after-free vulnerability in OBJECT's mChannel (ZDI-CAN-1032)

RESOLVED FIXED in mozilla2.0

Status

()

Core
DOM
P1
normal
RESOLVED FIXED
6 years ago
16 days ago

People

(Reporter: bsterne, Assigned: bz)

Tracking

({csectype-uaf})

Trunk
mozilla2.0
csectype-uaf
Points:
---
Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(blocking2.0 final+, blocking1.9.2 .17+, status1.9.2 .17-fixed, status1.9.1 .19-fixed)

Details

(Whiteboard: [sg:critical?][hardblocker][has patch])

Attachments

(1 attachment)

(Reporter)

Description

6 years ago
The following was sent to security@mozilla.org today:

ZDI-CAN-1032: Mozilla Firefox OBJECT mChannel Remote Code Execution Vulnerability

-- CVSS ----------------------------------------------------------------
9, (AV:N/AC:L/Au:N/C:P/I:P/A:C)

-- ABSTRACT ------------------------------------------------------------

TippingPoint has identified a vulnerability affecting the following products:

    Mozilla Firefox

-- VULNERABILITY DETAILS -----------------------------------------------

This vulnerability allows remote attackers to execute arbitrary code on vulnerable installations of Mozilla Firefox. User interaction is required to exploit this vulnerability in that the target must visit a malicious page.

The specific flaw exists within the OnChannelRedirect method. When an OBJECT element has no mChannel assigned, it is possible to call the |OnChannelRedirect| method, setting a nearly arbitrary object as the channel in use. |mChannel| will become a dangling pointer, allowing an attacker to execute arbitrary code under the context of the user running the browser.

Version(s)  tested: Firefox 3.6.13
Platform(s) tested: Windows XP SP3

From content/base/src/nsObjectLoadingContent.cpp:

nsObjectLoadingContent::OnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags)
{
// If we're already busy with a new load, cancel the redirect
if (aOldChannel != mChannel) {
return NS_BINDING_ABORTED;
}

if (mClassifier) {
mClassifier->OnRedirect(aOldChannel, aNewChannel);
}

mChannel = aNewChannel;
return NS_OK;
}

When an OBJECT element (implementation of nsIChannelEventSink interface) has no |mChannel| assigned, it is possible to call the |OnChannelRedirect| method, setting a nearly arbitrary object as the channel in use. The problem is that |mChannel| is a weak reference (as defined in content/base/src/nsObjectLoadingContent.h) and will become a dangling pointer after the garbage collection cycle.


The dangling pointer can be utilized by setting the "data" attribute to our OBJECT. This will call the |LoadObject| method, and load our OBJECT.

nsObjectLoadingContent::LoadObject(nsIURI* aURI,
                                   PRBool aNotify,
                                   const nsCString& aTypeHint,
                                   PRBool aForceLoad)
{
  ...
  if (mChannel) {
    ...
    mChannel->Cancel(NS_BINDING_ABORTED);
    ...
  }
  ...
}

-- CREDIT --------------------------------------------------------------

This vulnerability was discovered by:
    * regenrecht
bz, do you want this one?
This is basically the same as bug 634983.  Content shouldn't be able to QI the <object> to these random interfaces.  And on trunk it can't.  We need to backport that change to branch.
Depends on: 634983
fwiw, this looks sg:critical to me.
Actually, wait.  We just renamed the redirect function.  I can call asyncOnChannelRedirect from untrusted script fine on trunk....

I guess this is simple enough to fix by null-checking mChannel, though.

Updated

6 years ago
blocking2.0: --- → -
blocking1.9.2: --- → ?
status1.9.2: --- → wanted
status2.0: --- → unaffected
Summary: Use-after-free vulnerability in OBJECT's mChannel → Use-after-free vulnerability in OBJECT's mChannel (ZDI-CAN-1032)
Version: Trunk → 1.9.2 Branch
Fwiw, I don't think 2.0 is unaffected.  It just needs a slightly different testcase to trigger.

I'll put up a patch tomorrow; I need to spend some time auditing the other stuff <object> and company implement.
Assignee: nobody → bzbarsky
status2.0: unaffected → ?
Version: 1.9.2 Branch → Trunk
Priority: -- → P1
blocking1.9.2: ? → .15+

Comment 6

6 years ago
If this affects 2.0, should we reconsider blocking there?
Yeah :-(
blocking2.0: - → final+
Whiteboard: [sg:critical?] → [sg:critical?][hardblocker]
So, this is indeed confirmed critical?
What does "confirmed critical" mean? We don't have a testcase which does an actual heap-smashing attack, but it is easy for content to trigger use-after-free, which pretty much guarantees that it can be weaponized.
Sorry for the lag here; I did do the audit last week, and this plus the image loading content stuff from bug 634983 seem to be the only issues.
Oh, and the long-term-correct fix is to stop allowing untrusted content to access this interface, but the upcoming patch will fix things for now.
Created attachment 515685 [details] [diff] [review]
fix
Attachment #515685 - Flags: review?(jst)
Whiteboard: [sg:critical?][hardblocker] → [need review][sg:critical?][hardblocker]
Comment on attachment 515685 [details] [diff] [review]
fix

This applies to both branches with only a bit of fuzz.

The other option is to implement the channel redirect listener on a non-scriptable helper object instead of on the element itself.  jst, let me know if you'd prefer that?
Attachment #515685 - Flags: approval1.9.2.15?
Attachment #515685 - Flags: approval1.9.1.18?

Updated

6 years ago
Whiteboard: [need review][sg:critical?][hardblocker] → [need review][sg:critical?][hardblocker][has fix]

Updated

6 years ago
Whiteboard: [need review][sg:critical?][hardblocker][has fix] → [need review][sg:critical?][hardblocker][has patch]
Comment on attachment 515685 [details] [diff] [review]
fix

I think this'll do for now, until we have bindings that lets us selectively expose stuff only where we intend to expose stuff...
Attachment #515685 - Flags: review?(jst) → review+
Whiteboard: [need review][sg:critical?][hardblocker][has patch] → [need landing][sg:critical?][hardblocker][has patch]
Fix landed:

http://hg.mozilla.org/mozilla-central/rev/262b38ced70e
Status: NEW → RESOLVED
Last Resolved: 6 years ago
Resolution: --- → FIXED
Flags: in-testsuite?
Whiteboard: [need landing][sg:critical?][hardblocker][has patch] → [sg:critical?][hardblocker][has patch]
Target Milestone: --- → mozilla2.0

Comment 16

6 years ago
Comment on attachment 515685 [details] [diff] [review]
fix

approved for 1.9.2.15 and 1.9.1.18
Attachment #515685 - Flags: approval1.9.2.15?
Attachment #515685 - Flags: approval1.9.2.15+
Attachment #515685 - Flags: approval1.9.1.18?
Attachment #515685 - Flags: approval1.9.1.18+
Pushed:
  http://hg.mozilla.org/releases/mozilla-1.9.2/rev/c24f21581d77
  http://hg.mozilla.org/releases/mozilla-1.9.1/rev/442b50206d50
status1.9.1: --- → .18-fixed
status1.9.2: wanted → .15-fixed
status2.0: ? → ---
The "3.6.15" we're releasing today does not fix this bug, the release containing this bug fix has been renamed to "3.6.16" and the bugzilla flags will be updated to reflect that soon. Today's release is a re-release of 3.6.14 plus a fix for a bug that prevented many Java applets from starting up.
Alias: CVE-2011-0065
Group: core-security
Keywords: csectype-uaf
You need to log in before you can comment on or make changes to this bug.