Closed Bug 756241 (CVE-2012-3964) Opened 13 years ago Closed 13 years ago

Heap-use-after-free READ 8 in gfxTextRun::GetUserData

Categories

(Core :: Layout: Text and Fonts, defect)

defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla15
Tracking Status
firefox14 + affected
firefox15 --- fixed
firefox-esr10 --- unaffected

People

(Reporter: inferno, Assigned: MatsPalmgren_bugz)

References

Details

(5 keywords, Whiteboard: [sg:critical][asan][advisory-tracking+])

Attachments

(4 files, 1 obsolete file)

Attached file Testcase
Reproduces on trunk 20120517130245 http://hg.mozilla.org/mozilla-central/rev/895e12563245 ================================================================= ==6180== ERROR: AddressSanitizer heap-use-after-free on address 0x7f861c5860b8 at pc 0x7f863c987298 bp 0x7fff028995e0 sp 0x7fff028995d8 READ of size 8 at 0x7f861c5860b8 thread T0 #0 0x7f863c987298 in gfxTextRun::GetUserData() const src/modules/zlib/src/inffast.c:0 0x7f861c5860b8 is located 56 bytes inside of 6712-byte region [0x7f861c586080,0x7f861c587ab8) freed by thread T0 here: #0 0x4244a2 in free #1 0x7f863c9941bd in nsTextFrame::ClearTextRuns() src/layout/generic/nsTextFrame.h:432 previously allocated by thread T0 here: #0 0x424562 in malloc #1 0x7f863e38da84 in gfxTextRun::AllocateStorageForTextRun(unsigned long, unsigned int) src/gfx/thebes/gfxFont.cpp:4290 ==6180== ABORTING Stats: 125M malloced (131M for red zones) by 252339 calls Stats: 28M realloced by 12734 calls Stats: 85M freed by 119994 calls Stats: 0M really freed by 0 calls Stats: 292M (74798 full pages) mmaped in 73 calls mmaps by size class: 8:212979; 9:40955; 10:12285; 11:12282; 12:3072; 13:2048; 14:1536; 15:384; 16:576; 17:96; 18:144; 19:40; 20:16; mallocs by size class: 8:191798; 9:34053; 10:9717; 11:10403; 12:2011; 13:1813; 14:1446; 15:277; 16:565; 17:65; 18:139; 19:39; 20:13; frees by size class: 8:80912; 9:21306; 10:5944; 11:7541; 12:1292; 13:971; 14:1169; 15:231; 16:498; 17:52; 18:29; 19:38; 20:11; rfrees by size class: Stats: malloc large: 256 small slow: 1500 Shadow byte and word: 0x1ff0c38b0c17: fd 0x1ff0c38b0c10: fd fd fd fd fd fd fd fd More shadow bytes: 0x1ff0c38b0bf0: fa fa fa fa fa fa fa fa 0x1ff0c38b0bf8: fa fa fa fa fa fa fa fa 0x1ff0c38b0c00: fa fa fa fa fa fa fa fa 0x1ff0c38b0c08: fa fa fa fa fa fa fa fa =>0x1ff0c38b0c10: fd fd fd fd fd fd fd fd 0x1ff0c38b0c18: fd fd fd fd fd fd fd fd 0x1ff0c38b0c20: fd fd fd fd fd fd fd fd 0x1ff0c38b0c28: fd fd fd fd fd fd fd fd 0x1ff0c38b0c30: fd fd fd fd fd fd fd fd
Better stack with full symbols. ================================================================= ==11185== ERROR: AddressSanitizer heap-use-after-free on address 0x7f1f63be60b8 at pc 0x7f1f89bf5ff7 bp 0x7fffc63e9670 sp 0x7fffc63e9668 READ of size 8 at 0x7f1f63be60b8 thread T0 #0 0x7f1f89bf5ff7 in gfxTextRun::GetUserData() const firefox/src/modules/zlib/src/inffast.c:0 #1 0x7f1f89c404df in UnhookTextRunFromFrames(gfxTextRun*, nsTextFrame*) firefox/src/layout/generic/nsTextFrameThebes.cpp:476 #2 0x7f1f89c14cad in nsTextFrame::ClearTextRun(nsTextFrame*, nsTextFrame::TextRunType) firefox/src/layout/generic/nsTextFrameThebes.cpp:4305 #3 0x7f1f89c3a453 in nsTextFrame::ClearTextRuns() firefox/src/layout/generic/nsTextFrame.h:433 #4 0x7f1f89c3cc15 in nsContinuingTextFrame::DestroyFrom(nsIFrame*) firefox/src/layout/generic/nsTextFrameThebes.cpp:4043 #5 0x7f1f8904b588 in nsIFrame::Destroy() firefox/src/layout/xul/base/src/../../../generic/nsIFrame.h:596 #6 0x7f1f897fd250 in nsContainerFrame::RemoveFrame(mozilla::layout::FrameChildListID, nsIFrame*) firefox/src/layout/generic/nsContainerFrame.cpp:230 #7 0x7f1f89c966d4 in RemoveInFlows(nsIFrame*, nsIFrame*) firefox/src/layout/generic/nsTextFrameThebes.cpp:7032 #8 0x7f1f89c9549a in nsTextFrame::SetLength(int, nsLineLayout*, unsigned int) firefox/src/layout/generic/nsTextFrameThebes.cpp:7135 #9 0x7f1f89c993e6 in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, bool, nsHTMLReflowMetrics&, unsigned int&) firefox/src/layout/generic/nsTextFrameThebes.cpp:7364 #10 0x7f1f89aa9d38 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:875 #11 0x7f1f8981ea13 in nsFirstLetterFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsFirstLetterFrame.cpp:267 #12 0x7f1f89aa99bf in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:863 #13 0x7f1f8976717f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3846 #14 0x7f1f89760bda in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3642 #15 0x7f1f89753657 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3494 #16 0x7f1f89741e9c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2582 #17 0x7f1f897272e1 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2032 #18 0x7f1f8971ad7f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1081 #19 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #20 0x7f1f89953ee3 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:560 #21 0x7f1f8994e5e2 in nsHTMLScrollFrame::TryLayout(ScrollReflowState*, nsHTMLReflowMetrics*, bool, bool, bool, unsigned int*) firefox/src/layout/generic/nsGfxScrollFrame.cpp:405 #22 0x7f1f8995a2e3 in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:717 #23 0x7f1f8995db5f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:901 #24 0x7f1f897ab37b in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) firefox/src/layout/generic/nsBlockReflowContext.cpp:295 #25 0x7f1f8974c30f in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3218 #26 0x7f1f897419f6 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2526 #27 0x7f1f897272e1 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2032 #28 0x7f1f8971ad7f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1081 #29 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #30 0x7f1f899d996c in nsCanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsCanvasFrame.cpp:461 #31 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #32 0x7f1f89953ee3 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:560 #33 0x7f1f8994e5e2 in nsHTMLScrollFrame::TryLayout(ScrollReflowState*, nsHTMLReflowMetrics*, bool, bool, bool, unsigned int*) firefox/src/layout/generic/nsGfxScrollFrame.cpp:405 #34 0x7f1f8995a1a4 in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:708 #35 0x7f1f8995db5f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:901 #36 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #37 0x7f1f89d32ca6 in ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsViewportFrame.cpp:232 #38 0x7f1f89499478 in PresShell::DoReflow(nsIFrame*, bool) firefox/src/layout/base/nsPresShell.cpp:7421 #39 0x7f1f894c7a5d in PresShell::ProcessReflowCommands(bool) firefox/src/layout/base/nsPresShell.cpp:7562 #40 0x7f1f894c616d in PresShell::FlushPendingNotifications(mozFlushType) firefox/src/layout/base/nsPresShell.cpp:3879 #41 0x7f1f8956c19b in nsRefreshDriver::Notify(nsITimer*) firefox/src/layout/base/nsRefreshDriver.cpp:428 #42 0x7f1f938dca16 in nsTimerImpl::Fire() firefox/src/xpcom/threads/nsTimerImpl.cpp:512 #43 0x7f1f938de58c in nsTimerEvent::Run() firefox/src/xpcom/threads/nsTimerImpl.cpp:593 #44 0x7f1f938a0a9e in nsThread::ProcessNextEvent(bool, bool*) firefox/src/xpcom/threads/nsThread.cpp:657 #45 0x7f1f9353084d in NS_ProcessNextEvent_P(nsIThread*, bool) firefox/src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:245 #46 0x7f1f92a44236 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) firefox/src/ipc/glue/MessagePump.cpp:114 #47 0x7f1f93b4f7ea in MessageLoop::RunInternal() firefox/src/ipc/chromium/src/base/message_loop.cc:209 #48 0x7f1f93b4f633 in MessageLoop::RunHandler() firefox/src/ipc/chromium/src/base/message_loop.cc:202 #49 0x7f1f93b4f518 in MessageLoop::Run() firefox/src/ipc/chromium/src/base/message_loop.cc:176 #50 0x7f1f91f8008e in nsBaseAppShell::Run() firefox/src/widget/xpwidgets/nsBaseAppShell.cpp:198 #51 0x7f1f90bbcaa8 in nsAppStartup::Run() firefox/src/toolkit/components/startup/nsAppStartup.cpp:295 #52 0x7f1f87b604f2 in XREMain::XRE_mainRun() firefox/src/toolkit/xre/nsAppRunner.cpp:3792 #53 0x7f1f87b66602 in XREMain::XRE_main(int, char**, nsXREAppData const*) firefox/src/toolkit/xre/nsAppRunner.cpp:3869 #54 0x7f1f87b69a58 in XRE_main firefox/src/toolkit/xre/nsAppRunner.cpp:3945 #55 0x40a773 in do_main(int, char**) firefox/src/browser/app/nsBrowserApp.cpp:190 #56 0x40830e in main firefox/src/browser/app/nsBrowserApp.cpp:277 #57 0x7f1fa18bdc4d in ?? ??:0 0x7f1f63be60b8 is located 56 bytes inside of 6712-byte region [0x7f1f63be6080,0x7f1f63be7ab8) freed by thread T0 here: #0 0x4a32e2 in free ??:0 #1 0x7f1f9fe2c673 in moz_free firefox/src/memory/mozalloc/mozalloc.cpp:82 #2 0x7f1f89d22d53 in gfxTextRun::operator delete(void*) firefox/src/gfx/thebes/gfxFont.h:2366 #3 0x7f1f93ec4898 in ~gfxTextRun firefox/src/gfx/thebes/gfxFont.cpp:4351 #4 0x7f1f89c14df2 in nsTextFrame::ClearTextRun(nsTextFrame*, nsTextFrame::TextRunType) firefox/src/layout/generic/nsTextFrameThebes.cpp:4309 #5 0x7f1f89c3a43a in nsTextFrame::ClearTextRuns() firefox/src/layout/generic/nsTextFrame.h:431 #6 0x7f1f89c3cc15 in nsContinuingTextFrame::DestroyFrom(nsIFrame*) firefox/src/layout/generic/nsTextFrameThebes.cpp:4043 #7 0x7f1f8904b588 in nsIFrame::Destroy() firefox/src/layout/xul/base/src/../../../generic/nsIFrame.h:596 #8 0x7f1f897fd250 in nsContainerFrame::RemoveFrame(mozilla::layout::FrameChildListID, nsIFrame*) firefox/src/layout/generic/nsContainerFrame.cpp:230 #9 0x7f1f89c966d4 in RemoveInFlows(nsIFrame*, nsIFrame*) firefox/src/layout/generic/nsTextFrameThebes.cpp:7032 #10 0x7f1f89c9549a in nsTextFrame::SetLength(int, nsLineLayout*, unsigned int) firefox/src/layout/generic/nsTextFrameThebes.cpp:7135 #11 0x7f1f89c993e6 in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, bool, nsHTMLReflowMetrics&, unsigned int&) firefox/src/layout/generic/nsTextFrameThebes.cpp:7364 #12 0x7f1f89aa9d38 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:875 #13 0x7f1f8981ea13 in nsFirstLetterFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsFirstLetterFrame.cpp:267 #14 0x7f1f89aa99bf in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:863 #15 0x7f1f8976717f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3846 #16 0x7f1f89760bda in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3642 #17 0x7f1f89753657 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3494 #18 0x7f1f89741e9c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2582 #19 0x7f1f897272e1 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2032 #20 0x7f1f8971ad7f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1081 #21 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #22 0x7f1f89953ee3 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:560 #23 0x7f1f8994e5e2 in nsHTMLScrollFrame::TryLayout(ScrollReflowState*, nsHTMLReflowMetrics*, bool, bool, bool, unsigned int*) firefox/src/layout/generic/nsGfxScrollFrame.cpp:405 #24 0x7f1f8995a2e3 in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:717 #25 0x7f1f8995db5f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:901 #26 0x7f1f897ab37b in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) firefox/src/layout/generic/nsBlockReflowContext.cpp:295 #27 0x7f1f8974c30f in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3218 #28 0x7f1f897419f6 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2526 #29 0x7f1f897272e1 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2032 previously allocated by thread T0 here: #0 0x4a33a2 in malloc ??:0 #1 0x7f1f9fe2cad3 in moz_malloc firefox/src/memory/mozalloc/mozalloc.cpp:97 #2 0x7f1f93ec31b6 in gfxTextRun::AllocateStorageForTextRun(unsigned long, unsigned int) firefox/src/gfx/thebes/gfxFont.cpp:4290 #3 0x7f1f93ea724f in gfxTextRun::Create(gfxTextRunFactory::Parameters const*, unsigned int, gfxFontGroup*, unsigned int) firefox/src/gfx/thebes/gfxFont.cpp:4307 #4 0x7f1f93eaaa15 in gfxFontGroup::MakeTextRun(unsigned char const*, unsigned int, gfxTextRunFactory::Parameters const*, unsigned int) firefox/src/gfx/thebes/gfxFont.cpp:3392 #5 0x7f1f89c0d3d1 in gfxTextRun* MakeTextRun<unsigned char>(unsigned char const*, unsigned int, gfxFontGroup*, gfxTextRunFactory::Parameters const*, unsigned int) firefox/src/layout/generic/nsTextFrameThebes.cpp:561 #6 0x7f1f89c00552 in BuildTextRunsScanner::BuildTextRunForFrames(void*) firefox/src/layout/generic/nsTextFrameThebes.cpp:2035 #7 0x7f1f89bf6bed in BuildTextRunsScanner::FlushFrames(bool, bool) firefox/src/layout/generic/nsTextFrameThebes.cpp:1400 #8 0x7f1f89c1a0a8 in BuildTextRuns(gfxContext*, nsTextFrame*, nsIFrame*, nsLineList_iterator const*, nsTextFrame::TextRunType) firefox/src/layout/generic/nsTextFrameThebes.cpp:1329 #9 0x7f1f89c15d24 in nsTextFrame::EnsureTextRun(nsTextFrame::TextRunType, gfxContext*, nsIFrame*, nsLineList_iterator const*, unsigned int*) firefox/src/layout/generic/nsTextFrameThebes.cpp:2441 #10 0x7f1f89c99c92 in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, bool, nsHTMLReflowMetrics&, unsigned int&) firefox/src/layout/generic/nsTextFrameThebes.cpp:7428 #11 0x7f1f89aa9d38 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:875 #12 0x7f1f8981ea13 in nsFirstLetterFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsFirstLetterFrame.cpp:267 #13 0x7f1f89aa99bf in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:863 #14 0x7f1f8976717f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3846 #15 0x7f1f89760bda in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3642 #16 0x7f1f89753657 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3494 #17 0x7f1f89741e9c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2582 #18 0x7f1f897272e1 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2032 #19 0x7f1f8971ad7f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1081 #20 0x7f1f8980b367 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:940 #21 0x7f1f89953ee3 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:560 #22 0x7f1f8995983a in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:660 ==11185== ABORTING Stats: 143M malloced (155M for red zones) by 330631 calls Stats: 43M realloced by 18519 calls Stats: 108M freed by 213111 calls Stats: 0M really freed by 0 calls Stats: 328M (84016 full pages) mmaped in 82 calls mmaps by size class: 8:262128; 9:49146; 10:16380; 11:16376; 12:3072; 13:2048; 14:1536; 15:384; 16:512; 17:128; 18:144; 19:56; 20:16; mallocs by size class: 8:248923; 9:44440; 10:15218; 11:15558; 12:2240; 13:1753; 14:1401; 15:289; 16:497; 17:112; 18:137; 19:49; 20:14; frees by size class: 8:149036; 9:35074; 10:11947; 11:12608; 12:1465; 13:883; 14:1212; 15:242; 16:433; 17:98; 18:56; 19:46; 20:11; rfrees by size class: Stats: malloc large: 312 small slow: 1729 Shadow byte and word: 0x1fe3ec77cc17: fd 0x1fe3ec77cc10: fd fd fd fd fd fd fd fd More shadow bytes: 0x1fe3ec77cbf0: fa fa fa fa fa fa fa fa 0x1fe3ec77cbf8: fa fa fa fa fa fa fa fa 0x1fe3ec77cc00: fa fa fa fa fa fa fa fa 0x1fe3ec77cc08: fa fa fa fa fa fa fa fa =>0x1fe3ec77cc10: fd fd fd fd fd fd fd fd 0x1fe3ec77cc18: fd fd fd fd fd fd fd fd 0x1fe3ec77cc20: fd fd fd fd fd fd fd fd 0x1fe3ec77cc28: fd fd fd fd fd fd fd fd 0x1fe3ec77cc30: fd fd fd fd fd fd fd fd
Component: General → Layout: Text
Product: Firefox → Core
QA Contact: general → layout.fonts-and-text
We're using a deleted gfxTextRun.
Assignee: nobody → matspal
Severity: normal → critical
Keywords: crash, testcase
OS: Linux → All
Hardware: x86_64 → All
Whiteboard: [sg:critical][asan]
We're calling SetLength on a text frame which leads to removing its next-in-flows, in RemoveInFlows(). The text frames all share the same text run. The frame we decide to remove is 0x7fffe4720750 (cyan color). DestroyFrom calls ClearTextRuns() which finds the first frame of the text run chain, which is 0x7fffd9541a90 (magenta). But RemoveInFlows has unhooked the frames to remove from the continuation chain: http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#6951 so we only clear 0x7fffd9541a90 and 0x7fffe4720880 (green), which is its new next-in-flow (we decide to keep that (empty) frame because we don't want to make its parent letter-frame have no children). Since we started from the first frame (aStartContinuation=(nil)), ClearAllTextRunReferences removes the TEXT_IN_TEXTRUN_USER_DATA bit http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#398 which makes ClearTextRun delete the text run. http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#4259 The crash occurs because ClearTextRuns() calls ClearTextRun() twice on this text run (GetTextRun(nsTextFrame::eNotInflated) returns mTextRun when not using font-inflation). http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrame.h#361 http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrame.h#383 http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#4237 But calling ClearTextRun() twice on the same text run is normally just redundant since mTextRun should be null after the first call, since we expect *this* frame will be reached when walking the continuations. And even if we avoid calling it twice, we would crash anyway for a slightly different frame tree -- had there been one more next-in-flow [after the cyan frame] we would crash in DestroyFrame when it calls ClearTextRuns(). So, the fix is to call ClearTextRuns() with the continuation chain intact, then unhook the frames to remove and call RemoveFrame.
Attached patch fix (obsolete) — Splinter Review
The fix is to call ClearTextRuns() on the first and and last of the frames being removed, since it's only those two that can share text run with frames not being removed. I'm also adding a MOZ_ASSERT about the text run actually being null after UnhookTextRunFromFrames, which will abort if 'this' in ClearTextRun isn't in the continuation chain of the frame referenced by the text run (ie. we didn't actually unhook it (call RemoveTextRun)). https://tbpl.mozilla.org/?usebuildbot=1&tree=Try&rev=e445217e4d50
Attachment #626066 - Flags: review?(roc)
Attached patch fixSplinter Review
(fixing the commit message)
Attachment #626066 - Attachment is obsolete: true
Attachment #626066 - Flags: review?(roc)
Attachment #626068 - Flags: review?(roc)
Attached patch crashtestSplinter Review
Flags: in-testsuite?
Target Milestone: --- → mozilla15
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Although we need to confirm by testing, I'm assuming this is fairly stable code and likely affects old branches.
Actually font inflation (Bug 627842) didn't land until Firefox 11 so ESR-10 should not be affected.
The bug is also in ESR-10, the textrun added for font-inflation just made it more likely to occur.
Verified fixed using testcase in my 6/9 ASAN trunk build on OS X.
Status: RESOLVED → VERIFIED
Whiteboard: [sg:critical][asan] → [sg:critical][asan][advisory-tracking+]
Alias: CVE-2012-3964
Bug 791601 appears to be a slight variation of this bug, so we shouldn't make this bug public before that bug is. (I think the testcase here plus the slight code adjustment in bug 791601 might be enough to figure out how to trigger the new crash)
Depends on: 791601
Group: core-security
Flags: in-testsuite? → in-testsuite+
Backed out the crash test in https://hg.mozilla.org/mozilla-central/rev/c33931682b68 - because of bug 876159 we weren't marking the run as failing (and wouldn't have marked it as failing even if this or any other test in the run failed), but the 10000 assertions and the millions of warnings were pushing Linux debug crashtest logs over the 50MB limit.
Flags: in-testsuite+ → in-testsuite?
Flags: sec-bounty+
From the B2G failure: 20:02:22 INFO - JavaScript error: http://10.0.2.2:8888/tests/layout/generic/crashtests/756241.html, line 1: TypeError: document.body is null I'll try to make the test more robust when I get some time... unless some kind soul beats me to it :-)
Flags: needinfo?(mats)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: