Closed Bug 831095 (CVE-2013-0775) Opened 12 years ago Closed 12 years ago

Use-After-Free crash @xul!nsImageLoadingContent::OnStopContainer


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

21 Branch
Windows 8
Not set



blocking-b2g tef+
Tracking Status
firefox18 --- wontfix
firefox19 + verified
firefox20 + verified
firefox21 + verified
firefox-esr17 19+ verified
b2g18 19+ fixed
b2g18-v1.0.0 --- wontfix
b2g18-v1.0.1 --- fixed


(Reporter: nils, Assigned: khuey)



(4 keywords, Whiteboard: [asan][adv-main19+][adv-esr1703+])


(2 files)

The attached testcase crashes when loaded in latest Firefox nightly. Crashes at random memory addresses.

Stack trace on windows (this was with the previous testcase which loaded a jpeg file instead of png from data uri):
64fcc61e ff5128          call    dword ptr [ecx+28h]  ds:002b:00000029=????????
0:000:x86> cdb: Reading initial command 'kp 16;q'
ChildEBP RetAddr  
0033cb58 64e6eac6 xul!nsImageLoadingContent::OnStopContainer(class imgIRequest * aRequest = 0x07dc8e00, class imgIContainer * aContainer = 0x0779a790)+0x37
0033cb6c 64e2229d xul!imgRequestProxy::OnStopContainer(class imgIContainer * image = 0x0779a790)+0x36
0033cbfc 64dfd62b xul!imgRequest::OnStopDecode(class imgIRequest * aRequest = 0x00000000, tag_nsresult aStatus = NS_OK (0n0), wchar_t * aStatusArg = 0x00000000 "")+0xad
0033cc24 6501fca4 xul!mozilla::image::Decoder::PostDecodeDone(void)+0x67
*** WARNING: Unable to verify checksum for C:\Program Files (x86)\Mozilla Firefox\gkmedias.dll
0033cc2c 66072e8f xul!mozilla::image::term_source(struct jpeg_decompress_struct * jd = 0x07d47438)+0x14
0033cc38 64f86b63 gkmedias!jpeg_finish_decompress(struct jpeg_decompress_struct * cinfo = 0x07d47438)+0x5a
0033ce74 64f5beaf xul!mozilla::image::nsJPEGDecoder::WriteInternal(char * aBuffer = 0x07df5008 "G???", unsigned int aCount = 0x18e)+0x359
0033ce90 64faf970 xul!mozilla::image::RasterImage::WriteToDecoder(char * aBuffer = 0x07df5008 "G???", unsigned int aCount = 0x18e)+0x41
0033ceac 64f6ff0b xul!mozilla::image::RasterImage::DecodeSomeData(unsigned int aMaxBytes = 0x1000)+0x37
0033ceec 64fbaa9b xul!mozilla::image::RasterImage::DecodeWorker::DecodeSomeOfImage(class mozilla::image::RasterImage * aImg = 0x0779a790, mozilla::image::RasterImage::DecodeWorker::DecodeType aDecodeType = DECODE_TYPE_NORMAL (0n0))+0xbc
0033cf28 64e91dbf xul!mozilla::image::RasterImage::DecodeWorker::Run(void)+0xb6
0033cf98 6503c86f xul!nsThread::ProcessNextEvent(bool mayWait = false, bool * result = 0x0033cfd4)+0x2cf
0033cfcc 6504ca2b xul!mozilla::ipc::MessagePump::Run(class base::MessagePump::Delegate * aDelegate = 0x00a42001)+0x5f
0033d004 6504c9d3 xul!MessageLoop::RunHandler(void)+0x21
0033d020 6502fc8f xul!MessageLoop::Run(void)+0x15
0033d02c 6504c953 xul!nsBaseAppShell::Run(void)+0x34
0033ef80 65076c9d xul!nsAppShell::Run(void)+0x4e
0033ef8c 64fbc83a xul!nsAppStartup::Run(void)+0x1e
0033f058 6501522d xul!XREMain::XRE_mainRun(void)+0x405
0033f074 65037bb4 xul!XREMain::XRE_main(int argc = 0n5, char ** argv = 0x00134660, struct nsXREAppData * aAppData = 0x00c332e0)+0xde
*** WARNING: Unable to verify checksum for firefox.exe
0033f18c 00c31742 xul!XRE_main(int argc = 0n5, char ** argv = 0x00134660, struct nsXREAppData * aAppData = 0x00c332e0, unsigned int aFlags = 0)+0x30
0033fc64 00c31a64 firefox!wmain(int argc = 0n5, wchar_t ** argv = 0x00132e90)+0x742
Attachment #702600 - Attachment mime type: text/plain → text/html
ASAN output:

==20176== ERROR: AddressSanitizer heap-use-after-free on address 0x7f900bfd0188 at pc 0x7f90777e5153 bp 0x7ffffd830730 sp 0x7ffffd830728
READ of size 8 at 0x7f900bfd0188 thread T0
    #0 0x7f90777e5152 in _ZN21nsImageLoadingContent6NotifyEP11imgIRequestiPK9nsIntRect /builds/slave/try-lnx64/build/content/base/src/nsImageLoadingContent.cpp:146
    #1 0x7f9076e0b2ab in _ZN15imgRequestProxy12OnStopDecodeEv /builds/slave/try-lnx64/build/image/src/imgRequestProxy.cpp:713
    #2 0x7f9076e1d283 in _ZN16imgStatusTracker10SyncNotifyEP15imgRequestProxy /builds/slave/try-lnx64/build/image/src/imgStatusTracker.cpp:433
    #3 0x7f9076e1f23e in _ZN24imgRequestNotifyRunnable3RunEv /builds/slave/try-lnx64/build/image/src/imgStatusTracker.cpp:289
0x7f900bfd0188 is located 8 bytes inside of 16-byte region [0x7f900bfd0180,0x7f900bfd0190)
freed by thread T0 here:
    #0 0x433730 in free ??:0
    #1 0x7f90777e6e08 in _ZdlPv /builds/slave/try-lnx64/build/../../../dist/include/mozilla/mozalloc.h:224
previously allocated by thread T0 here:
    #0 0x4337f0 in __interceptor_malloc ??:0
    #1 0x7f907e0b5228 in moz_xmalloc /builds/slave/try-lnx64/build/memory/mozalloc/mozalloc.cpp:54
    #2 0x7f9076eda7aa in _ZN21nsCSSFrameConstructor19InitAndRestoreFrameERK23nsFrameConstructorStateP10nsIContentP8nsIFrameS6_S6_b /builds/slave/try-lnx64/build/layout/base/nsCSSFrameConstructor.cpp:4506
    #3 0x7f9076ee1f4c in _ZN21nsCSSFrameConstructor23ConstructFramesFromItemER23nsFrameConstructorStateRNS_25FrameConstructionItemList8IteratorEP8nsIFrameR12nsFrameItems /builds/slave/try-lnx64/build/layout/base/nsCSSFrameConstructor.cpp:5506
Shadow byte and word:
  0x1ff2017fa031: fd
  0x1ff2017fa030: fd fd fd fd fd fd fd fd
More shadow bytes:
  0x1ff2017fa010: fd fd fd fd fd fd fd fd
  0x1ff2017fa018: fd fd fd fd fd fd fd fd
  0x1ff2017fa020: fa fa fa fa fa fa fa fa
  0x1ff2017fa028: fa fa fa fa fa fa fa fa
=>0x1ff2017fa030: fd fd fd fd fd fd fd fd
  0x1ff2017fa038: fd fd fd fd fd fd fd fd
  0x1ff2017fa040: fa fa fa fa fa fa fa fa
  0x1ff2017fa048: fa fa fa fa fa fa fa fa
  0x1ff2017fa050: fd fd fd fd fd fd fd fd
Stats: 763M malloced (935M for red zones) by 2315206 calls
Stats: 91M realloced by 137427 calls
Stats: 715M freed by 2121167 calls
Stats: 602M really freed by 1735359 calls
Stats: 820M (210041 full pages) mmaped in 204 calls
  mmaps   by size class: 8:737235; 9:147438; 10:32760; 11:24564; 12:6144; 13:3584; 14:2048; 15:1792; 16:1216; 17:1280; 18:48; 19:64; 20:28; 21:10; 22:3; 23:1;
  mallocs by size class: 8:1787993; 9:339499; 10:89657; 11:61196; 12:13384; 13:10402; 14:5231; 15:2703; 16:2718; 17:2221; 18:60; 19:81; 20:47; 21:10; 22:3; 23:1;
  frees   by size class: 8:1625836; 9:321315; 10:83377; 11:57123; 12:11731; 13:9386; 14:4920; 15:2569; 16:2530; 17:2204; 18:50; 19:68; 20:46; 21:8; 22:3; 23:1;
  rfrees  by size class: 8:1330385; 9:262065; 10:68831; 11:45742; 12:10394; 13:7007; 14:4565; 15:2309; 16:2006; 17:1904; 18:43; 19:64; 20:32; 21:8; 22:3; 23:1;
Stats: malloc large: 2424 small slow: 10417
==20176== ABORTING
Component: DOM: Events → DOM
Assignee: nobody → khuey
Ever confirmed: true
Keywords: sec-critical
Whiteboard: [asan]
Matt can you find a regression range for this?
Attached patch PatchSplinter Review
So, the immediate problem here is that an nsImageLoadingContent observer causes an attribute mutation, which fires a mutation event, which lets script synchronously mess with the observer list.  This attribute mutation was added in Bug 756419.  What I don't understand is why this only recently started crashing (it doesn't crash Aurora, for instance).

Regardless, the attached patch adds a script blocker and makes us happy.
Attachment #702947 - Flags: review?(bzbarsky)
Comment on attachment 702947 [details] [diff] [review]

Attachment #702947 - Flags: review?(bzbarsky) → review+
I can reproduce the crash in Firefox esr17, 18, 19beta, Aurora20.0a2 and Nightly21.0a1.

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0 ID:20130107124423
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 ID:20130104151925
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0 ID:20130109111322
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20130116 Firefox/20.0 ID:20130116042017
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130116 Firefox/21.0 ID:20130116031003
Ok, that makes more sense, and I think we can blame it on Bug 756419 then.

I was unable to get a crash on non-trunk branches, but I was using opt instead of debug there.
Comment on attachment 702947 [details] [diff] [review]

[Security approval request comment]
How easily could an exploit be constructed based on the patch?

Moderately difficult.  A motivated observer could audit all of the things that observe nsImageLoadingContent to see which are likely to trigger content script execution, and from there figure out how to mess up the observer list.

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?


Which older supported branches are affected by this flaw?

All supported branches.

If not all supported branches, which bug introduced the flaw?

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?

This backports to Aurora cleanly, Beta with trivial modifications, ESR 17 with slightly less trivial modifications.

How likely is this patch to cause regressions; how much testing does it need?

This patch is unlikely to cause regressions and needs limited testing.
Attachment #702947 - Flags: sec-approval?
Attachment #702947 - Flags: sec-approval? → sec-approval+
Comment on attachment 702947 [details] [diff] [review]

[Approval Request Comment]
Bug caused by (feature/regressing bug #): Bug 756419
User impact if declined: Exploitable security bug
Testing completed: Tested manually, on try, on m-c.
Risk to taking this patch (and alternatives if risky): Low risk
String or UUID changes made by this patch: None
Attachment #702947 - Flags: approval-mozilla-esr17?
Attachment #702947 - Flags: approval-mozilla-beta?
Attachment #702947 - Flags: approval-mozilla-b2g18?
Attachment #702947 - Flags: approval-mozilla-aurora?
Closed: 12 years ago
Resolution: --- → FIXED
Comment on attachment 702947 [details] [diff] [review]

Let's land this low risk sg:crit fix on all branches other than B2G. We'll let you know when this is ready to land for B2G.
Attachment #702947 - Flags: approval-mozilla-esr17?
Attachment #702947 - Flags: approval-mozilla-esr17+
Attachment #702947 - Flags: approval-mozilla-beta?
Attachment #702947 - Flags: approval-mozilla-beta+
Attachment #702947 - Flags: approval-mozilla-aurora?
Attachment #702947 - Flags: approval-mozilla-aurora+
Since this isn't on b2g18 yet, we'll track for v1.0.1 and approve after 1/25 when mozilla-b2g18 is open for landings.  See  for more info.
Confirmed crash 2013-01-15, m-c 
Verified fixed 2013-01-24, m-c 
Verified fixed 2013-01-24, Aurora
Verified fixed 2013-01-24, beta
Verified fixed 2013-01-24, 17.0.2esr
Flags: sec-bounty? → sec-bounty+
Comment on attachment 702947 [details] [diff] [review]

This can now be landed mozilla-b2g18, which is currently v1.0.1.
Attachment #702947 - Flags: approval-mozilla-b2g18? → approval-mozilla-b2g18+
Kyle, I'm guessing that what landed on esr17 is the closest to what needs to land on b2g18?
Target Milestone: --- → mozilla21
Whiteboard: [asan] → [asan][adv-main19+][adv-esr1703+]
Alias: CVE-2013-0775
Since Firefox 20 is now released, v1.0.1 branches are still open, and this is considered low risk, we can uplift to v1.0.1. Marking as tef+ and flipping status-b2g18-v1.0.1 to affected.
blocking-b2g: --- → tef+
Keywords: checkin-needed
This landed prior to v1.0.1 branching off.
Group: core-security
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.