Beginning on October 25th, 2016, Persona will no longer be an option for authentication on BMO. For more details see Persona Deprecated.
Last Comment Bug 540100 - nsTreeSelection EventListener Use-after-free Remote Code Execution Vulnerability (ZDI-CAN-669)
: nsTreeSelection EventListener Use-after-free Remote Code Execution Vulnerabil...
[sg:dupe 375928] fixed by bug 375928
: verified1.9.0.19, verified1.9.1
Product: Core
Classification: Components
Component: XUL (show other bugs)
: 1.9.1 Branch
: All All
: -- normal (vote)
: ---
Assigned To: Olli Pettay [:smaug]
: Neil Deakin
Depends on: CVE-2010-0175
  Show dependency treegraph
Reported: 2010-01-15 16:38 PST by Brandon Sterne (:bsterne)
Modified: 2010-07-15 19:13 PDT (History)
8 users (show)
dveditz: blocking1.9.0.19+
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Description Brandon Sterne (:bsterne) 2010-01-15 16:38:30 PST
Created attachment 421958 [details]
Proof of concept

ZDI-CAN-669: Mozilla Firefox nsTreeSelection EventListener Use-after-free Remote Code Execution Vulnerability

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

TippingPoint has identified a vulnerability affecting the following  products:

    Mozilla Firefox 3.5.x

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

This vulnerability allows remote attackers to execute arbitrary code on software utilizing a vulnerable version of Mozilla's Firefox. User interaction is required in that the victim must visit a malicious website or be coerced into opening a malicious document. 

The specific flaw exists within how the application handles particular events for an nsTreeSelection element. Upon execution of a "select" event the application will access an element without checking to see if it's been previously freed or not. Successful exploitation can lead to code execution under the context of the application.

This vulnerability occurs due to firing an event on an object that has already been freed and can be reproduced with the following code: 
<tree id="tr" flex="1">

tree = document.getElementById('tr');
tree.addEventListener("select", function (e) {}, false);
tree.view.selection.timedSelect(0, 5000);    // XXX: fire "select" event
in 5 seconds
tree.view.selection = null;                  // XXX: freed

Upon calling timedSelect on a tree.view.selection object, the application will instantiate a new timer, and call SelectCallback when it fires.


NS_IMETHODIMP nsTreeSelection::TimedSelect(PRInt32 aIndex, PRInt32
  PRBool suppressSelect = mSuppressed;

  if (aMsec != -1)
    mSuppressed = PR_TRUE;

  nsresult rv = Select(aIndex);
  if (NS_FAILED(rv))
    return rv;

  if (aMsec != -1) {
    mSuppressed = suppressSelect;
    if (!mSuppressed) {
      if (mSelectTimer)

      mSelectTimer = do_CreateInstance(";1");
      mSelectTimer->InitWithFuncCallback(SelectCallback, this, aMsec,  
// XXX

  return NS_OK;

At this point, a malicious individual will want to free the tree.view.selection the timer has been created for. Once the timer fires, the callback will then be executed. The following code will load the closure representing the callback, and then execute it.

nsTreeSelection::SelectCallback(nsITimer *aTimer, void *aClosure)
  nsTreeSelection* self = static_cast<nsTreeSelection*>(aClosure);
  if (self) {
    self->FireOnSelectHandler();        // XXX
    self->mSelectTimer = nsnull;

The select handler that's been fired, will load the code for the event and then execute it. At this point the tree.view.selection object has been freed.

  if (mSuppressed || !mTree)
    return NS_OK;

  nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
  NS_ASSERTION(boxObject, "no box object!");
  if (!boxObject)
  nsCOMPtr<nsIDOMElement> elt;

  nsRefPtr<nsPLDOMEvent> event =
    new nsPLDOMEvent(elt, NS_LITERAL_STRING("select"));
  event->RunDOMEventWhenSafe();     // XXX
  return NS_OK;

Version(s)  tested: FireFox 3.6.5 
Platform(s) tested: Windows XP SP3

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

This vulnerability was discovered by:
    * regenrecht

-- FURTHER DETAILS -----------------------------------------------------

If you have any questions, comments, concerns or require additional details please feel free to contact me via the following:

    Kate Fly
    Security Liaison
    Office: +1 512.681.8219

We can alternatively be reached via e-mail at:

Our PGP key is available from:
Comment 1 Olli Pettay [:smaug] 2010-02-08 05:54:27 PST
The PoC explanation isn't quite right.

But anyway, my bad, this is fixed on 1.9.2/trunk, see bug 375928.
Comment 2 Reed Loden [:reed] (use needinfo?) 2010-02-22 15:39:13 PST
Do we have reason to believe that this bug was discovered due to the check-in of the patch in bug 375928?
Comment 3 Olli Pettay [:smaug] 2010-03-04 12:26:19 PST
bug 375928 landed to branches.
Comment 4 Al Billings [:abillings] 2010-03-10 18:01:18 PST
Verified for 1.90 with  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2010031005 GranParadiso/3.0.19pre (.NET CLR 3.5.30729) on Windows XP.

Verified for 1.9.1 with  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20100310 Shiretoko/3.5.9pre (.NET CLR 3.5.30729).

Interestingly, the PoC will crash the debug builds of each completely but retail works fine.
Comment 5 Olli Pettay [:smaug] 2010-03-11 01:47:38 PST
(In reply to comment #4)
> Interestingly, the PoC will crash the debug builds of each completely but
> retail works fine.
You mean debug builds of and crash?
If so, what does the stack trace look like?
Comment 6 Al Billings [:abillings] 2010-03-11 12:44:04 PST
My debug builds had an issue so I clobbered and rebuilt. I don't see the issue with them now so it is all good.

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