Last Comment Bug 645565 - (CVE-2011-0070) Crash due to double-delete in nsDirIndexParser
(CVE-2011-0070)
: Crash due to double-delete in nsDirIndexParser
Status: RESOLVED FIXED
[sg:critical?]
: regression
Product: Core
Classification: Components
Component: Networking (show other bugs)
: unspecified
: x86 All
: -- critical (vote)
: mozilla5
Assigned To: Daniel Veditz [:dveditz]
:
:
Mentors:
Depends on:
Blocks: CVE-2008-0017
  Show dependency treegraph
 
Reported: 2011-03-27 15:49 PDT by Ian Beer
Modified: 2016-01-19 17:11 PST (History)
6 users (show)
rforbes: sec‑bounty+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
Macaw+
.1-fixed
.17+
.17-fixed
.19+
.19-fixed


Attachments
PoC - serves on localhost:8080 (781 bytes, text/x-python)
2011-03-27 15:51 PDT, Ian Beer
no flags Details
branch patch (1.45 KB, patch)
2011-03-29 13:34 PDT, Daniel Veditz [:dveditz]
cbiesinger: review+
christian: approval2.0+
christian: approval1.9.2.17+
christian: approval1.9.1.19+
Details | Diff | Splinter Review
trunk patch (minor context diff) (1.47 KB, patch)
2011-04-11 23:49 PDT, Daniel Veditz [:dveditz]
no flags Details | Diff | Splinter Review

Description Ian Beer 2011-03-27 15:49:32 PDT
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.16) Gecko/20110323 Ubuntu/10.10 (maverick) Firefox/3.6.16
Build Identifier: 3.6.16

By passing a malformed "application/http-index-format" response it is possible to cause a double delete in nsDirIndexParser leading to application crash and potential arbitrary code execution.

Details:

(All code below is from netwerk/streamconv/converters/nsDirIndexParser.cpp)

The nsDirIndexParser destructor deletes the member mFormat:

    101 nsDirIndexParser::~nsDirIndexParser() {
    102   delete[] mFormat;
    ...

This is usually fine as mFormat is either null (as it is initalised in the Init method) or a value which has been return by new in the method ParseFormat (line 206):

    178 nsDirIndexParser::ParseFormat(const char* aFormatStr) {
    179   // Parse a "200" format line, and remember the fields and their
    180   // ordering in mFormat. Multiple 200 lines stomp on each other.
    181 
    182   delete[] mFormat;
    183 
    184   // Lets find out how many elements we have.
    185   // easier to do this then realloc
    186   const char* pos = aFormatStr;
    187   unsigned int num = 0;
    188   do {
    189     while (*pos && nsCRT::IsAsciiSpace(PRUnichar(*pos)))
    190       ++pos;
    191     
    192     ++num;
    193     // There are a maximum of six allowed header fields (doubled plus
    194     // terminator, just in case) -- Bug 443299
    195     if (num > (2 * NS_ARRAY_LENGTH(gFieldTable)))
    196       return NS_ERROR_UNEXPECTED;
    197 
    198     if (! *pos)
    199       break;
    200 
    201     while (*pos && !nsCRT::IsAsciiSpace(PRUnichar(*pos)))
    202       ++pos;
    203 
    204   } while (*pos);
    205 
    206   mFormat = new int[num+1];

mFormat is deleted on entry to this function on line 182.

By passing a correct 200: line (with num < 14), mFormat will be assigned the value returned by new on line 206. If another 200: line is encountered, mFormat will be deleted on 182 but not set to null. If this second 200: line has an incorrect number of header fields it will fail the check on line 195 and an error value will be return, with mFormat retaining the value which was just deleted.

When this instance of nsDirIndexParser is destroyed the destructor will be called, deleting the same mFormat which has already been deleted, leading potentially to a crash or arbitrary code execution.

*******

A simple patch would be to set mFormat to null after it is deleted on line 182.

This issue appears to have been introduced by the fix for Bug 443299 which limited the number of header fields.

**************

I'll attach a simple python script which will generate the required "application/http-index-format" response (based on the PoC for Bug 443299)

Due to the nature of double delete bugs it may not crash every time and may crash with many different stack traces. I am able to reliably crash firefox here (sometimes having to mash f5 a bit, sometimes not.)

I've only tested on FF 3.6.16 32 bit Ubuntu 10.10.

Reproducible: Always

Steps to Reproduce:
Run attached python script

navigate to localhost:8080

crash. (try with different tabs open etc to get different traces)
Comment 1 Ian Beer 2011-03-27 15:51:53 PDT
Created attachment 522256 [details]
PoC - serves on localhost:8080
Comment 2 Ludovic Hirlimann [:Usul] 2011-03-28 02:54:05 PDT
I got this https://crash-stats.mozilla.com/report/index/bp-027acac0-cf23-4875-a0ca-abcbc2110328 while trying the test case with 4.0 final.
Comment 3 Daniel Veditz [:dveditz] 2011-03-29 12:35:32 PDT
I don't know why you'd crash over in nsHtml5HtmlAttributes::~nsHtml5HtmlAttributes but I guess general memory corruption.

On 3.6.17pre Mac I didn't crash after a bunch of reloads, but the test page doesn't do a lot and probably didn't trigger reallocating that memory (or if it freed something used elsewhere I might not crash until some later time). I crashed immediately (fatal abort) when running with MallocScribble turned on. QA should verify this fix using MallocScribble on Mac and gflags on Windows: don't rely on multiple reloads triggering a crash by chance.
Comment 4 Daniel Veditz [:dveditz] 2011-03-29 13:34:06 PDT
Created attachment 522781 [details] [diff] [review]
branch patch

Rather than null out mFormat right after the delete, what if we delay the delete until we've decided that the new format is good?
Comment 6 Christian :Biesinger (don't email me, ping me on IRC) 2011-03-29 18:44:56 PDT
Comment on attachment 522781 [details] [diff] [review]
branch patch

looks good, but have you considered making making mFormat an nsAutoArrayPtr?
Comment 7 Ian Beer 2011-04-05 07:05:25 PDT
Any particular reason the affected OS for this bug was changed to Windows CE?

I've changed it to 'All' now.
Comment 8 Daniel Veditz [:dveditz] 2011-04-05 14:09:43 PDT
gavin: any reason you pulled this out of blocking Macaw?
Comment 9 Daniel Veditz [:dveditz] 2011-04-11 23:49:16 PDT
Created attachment 525319 [details] [diff] [review]
trunk patch (minor context diff)
Comment 12 :Gavin Sharp [email: gavin@gavinsharp.com] 2011-04-20 11:39:32 PDT
(In reply to comment #8)
> gavin: any reason you pulled this out of blocking Macaw?

grr. mistake. :(

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