Last Comment Bug 765621 - (CVE-2012-3995) Out of bounds read in IsCSSWordSpacingSpace
(CVE-2012-3995)
: Out of bounds read in IsCSSWordSpacingSpace
Status: RESOLVED FIXED
[asan][advisory-tracking+]
: crash, sec-critical, testcase
Product: Core
Classification: Components
Component: Layout: Block and Inline (show other bugs)
: Trunk
: All All
: -- critical (vote)
: mozilla18
Assigned To: Mats Palmgren (:mats)
:
Mentors:
Depends on:
Blocks: 821479
  Show dependency treegraph
 
Reported: 2012-06-17 14:29 PDT by Abhishek Arya
Modified: 2014-07-22 13:04 PDT (History)
14 users (show)
rforbes: sec‑bounty+
mats: in‑testsuite+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
affected
affected
+
fixed
+
fixed
+
fixed
16+
fixed


Attachments
Testcase (2.14 KB, application/x-zip-compressed)
2012-06-17 14:29 PDT, Abhishek Arya
no flags Details
Better testcase, more reliable. (2.42 KB, application/x-zip-compressed)
2012-06-17 14:48 PDT, Abhishek Arya
no flags Details
stack for "ASSERTION: aPrevFrame must be the last continuation in its chain!" (4.38 KB, text/plain)
2012-07-11 17:37 PDT, Mats Palmgren (:mats)
no flags Details
Testcase (859 bytes, text/html)
2012-07-25 22:25 PDT, Abhishek Arya
no flags Details
stack + frame dump for "ASSERTION: aPrevFrame must be the last continuation in its chain!" (6.88 KB, text/html)
2012-09-11 17:26 PDT, Mats Palmgren (:mats)
no flags Details
wip (10.88 KB, patch)
2012-09-11 17:33 PDT, Mats Palmgren (:mats)
no flags Details | Diff | Review
fix (11.42 KB, patch)
2012-09-14 07:29 PDT, Mats Palmgren (:mats)
bzbarsky: review+
akeybl: approval‑mozilla‑aurora+
akeybl: approval‑mozilla‑beta+
Details | Diff | Review
ported to esr branch (12.62 KB, patch)
2012-09-24 22:19 PDT, Mats Palmgren (:mats)
bzbarsky: review+
bajaj.bhavana: approval‑mozilla‑esr10+
Details | Diff | Review

Description Abhishek Arya 2012-06-17 14:29:53 PDT
Created attachment 633924 [details]
Testcase

Reproduces on trunk, run testcase from command line. You also need the empty test.js as in archive.
20120617120215
http://hg.mozilla.org/mozilla-central/rev/b1a0fb2bdbf7

=================================================================
==27356== ERROR: AddressSanitizer heap-buffer-overflow on address 0x7fe2faee2f82 at pc 0x7fe3281b3821 bp 0x7fffdbd009d0 sp 0x7fffdbd009c8
READ of size 1 at 0x7fe2faee2f82 thread T0
    #0 0x7fe3281b3821 in nsTextFragment::CharAt(int) const firefox/src/modules/zlib/src/inffast.c:0
    #1 0x7fe328cca8a6 in IsCSSWordSpacingSpace(nsTextFragment const*, unsigned int, nsStyleText const*) firefox/src/layout/generic/nsTextFrameThebes.cpp:624
    #2 0x7fe328cc811f in PropertyProvider::GetSpacingInternal(unsigned int, unsigned int, gfxFont::Spacing*, bool) firefox/src/layout/generic/nsTextFrameThebes.cpp:2817
    #3 0x7fe328cc731d in PropertyProvider::GetSpacing(unsigned int, unsigned int, gfxFont::Spacing*) firefox/src/layout/generic/nsTextFrameThebes.cpp:2776
    #4 0x7fe33382d073 in GetAdjustedSpacing(gfxTextRun*, unsigned int, unsigned int, gfxTextRun::PropertyProvider*, gfxFont::Spacing*) firefox/src/gfx/thebes/gfxFont.cpp:4489
    #5 0x7fe333838a98 in gfxTextRun::BreakAndMeasureText(unsigned int, unsigned int, bool, double, gfxTextRun::PropertyProvider*, bool, double*, gfxFont::RunMetrics*, gfxFont::BoundingBoxType, gfxContext*, bool*, unsigned int*, bool, gfxBreakPriority*) firefox/src/gfx/thebes/gfxFont.cpp:4866
    #6 0x7fe328d43127 in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, bool, nsHTMLReflowMetrics&, unsigned int&) firefox/src/layout/generic/nsTextFrameThebes.cpp:7477
    #7 0x7fe328b54e98 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:836
    #8 0x7fe328b2586d in nsInlineFrame::ReflowInlineFrame(nsPresContext*, nsHTMLReflowState const&, nsInlineFrame::InlineReflowState&, nsIFrame*, unsigned int&) firefox/src/layout/generic/nsInlineFrame.cpp:680
    #9 0x7fe328b21f9d in nsInlineFrame::ReflowFrames(nsPresContext*, nsHTMLReflowState const&, nsInlineFrame::InlineReflowState&, nsHTMLReflowMetrics&, unsigned int&) firefox/src/layout/generic/nsInlineFrame.cpp:543
    #10 0x7fe328b1f2aa in nsInlineFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsInlineFrame.cpp:397
    #11 0x7fe328b54b1f in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:824
    #12 0x7fe328810a7f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3834
    #13 0x7fe32880a4da in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3630
    #14 0x7fe3287fcf57 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3482
    #15 0x7fe3287eb90c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2570
    #16 0x7fe3287d0d71 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2020
    #17 0x7fe3287c480f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1069
    #18 0x7fe328854a8b in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) firefox/src/layout/generic/nsBlockReflowContext.cpp:262
    #19 0x7fe3287f5d77 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3206
    #20 0x7fe3287eb466 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2514
    #21 0x7fe3287d0d71 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2020
    #22 0x7fe3287c480f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1069
    #23 0x7fe3288b4527 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:906
    #24 0x7fe3289fe1ae in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:516
    #25 0x7fe328a03a5a in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:616
    #26 0x7fe328a07d7f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:857
    #27 0x7fe328b54b1f in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:824
    #28 0x7fe328810a7f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3834
    #29 0x7fe32880a4da in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3630
    #30 0x7fe3287fcf57 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3482
    #31 0x7fe3287eb90c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2570
    #32 0x7fe3287d0d71 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2020
    #33 0x7fe3287c480f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1069
    #34 0x7fe328b54b1f in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) firefox/src/layout/generic/nsLineLayout.cpp:824
    #35 0x7fe328810a7f in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) firefox/src/layout/generic/nsBlockFrame.cpp:3834
    #36 0x7fe32880af87 in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) firefox/src/layout/generic/nsBlockFrame.cpp:3665
    #37 0x7fe3287fcf57 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3482
    #38 0x7fe3287eb90c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2570
    #39 0x7fe3287d0d71 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2020
    #40 0x7fe3287c480f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1069
    #41 0x7fe328854a8b in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) firefox/src/layout/generic/nsBlockReflowContext.cpp:262
    #42 0x7fe3287f5d77 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:3206
    #43 0x7fe3287eb466 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) firefox/src/layout/generic/nsBlockFrame.cpp:2514
    #44 0x7fe3287d0d71 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) firefox/src/layout/generic/nsBlockFrame.cpp:2020
    #45 0x7fe3287c480f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsBlockFrame.cpp:1069
    #46 0x7fe3288b4527 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:906
    #47 0x7fe328a83b57 in nsCanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsCanvasFrame.cpp:429
    #48 0x7fe3288b4527 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:906
    #49 0x7fe3289fe1ae in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) firefox/src/layout/generic/nsGfxScrollFrame.cpp:516
    #50 0x7fe328a03a5a in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:616
    #51 0x7fe328a07d7f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsGfxScrollFrame.cpp:857
    #52 0x7fe3288b4527 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) firefox/src/layout/generic/nsContainerFrame.cpp:906
    #53 0x7fe328ddbb81 in ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) firefox/src/layout/generic/nsViewportFrame.cpp:200
    #54 0x7fe32853d016 in PresShell::DoReflow(nsIFrame*, bool) firefox/src/layout/base/nsPresShell.cpp:7382
    #55 0x7fe32856aaad in PresShell::ProcessReflowCommands(bool) firefox/src/layout/base/nsPresShell.cpp:7523
    #56 0x7fe3285691bd in PresShell::FlushPendingNotifications(mozFlushType) firefox/src/layout/base/nsPresShell.cpp:3852
    #57 0x7fe32836ba9f in DocumentViewerImpl::LoadComplete(unsigned int) firefox/src/layout/base/nsDocumentViewer.cpp:982
    #58 0x7fe32fbd7a68 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, unsigned int) firefox/src/docshell/base/nsDocShell.cpp:6241
    #59 0x7fe32fbcf7a1 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, unsigned int) firefox/src/docshell/base/nsDocShell.cpp:6072
    #60 0x7fe32fbd0965 in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, unsigned int) firefox/src/modules/zlib/src/inffast.c:0
    #61 0x7fe32fcd5004 in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, unsigned int) firefox/src/uriloader/base/nsDocLoader.cpp:1352
    #62 0x7fe32fcd2a15 in nsDocLoader::doStopDocumentLoad(nsIRequest*, unsigned int) firefox/src/uriloader/base/nsDocLoader.cpp:930
    #63 0x7fe32fccbc68 in nsDocLoader::DocLoaderIsEmpty(bool) firefox/src/uriloader/base/nsDocLoader.cpp:822
0x7fe2faee2f82 is located 0 bytes to the right of 2-byte region [0x7fe2faee2f80,0x7fe2faee2f82)
allocated by thread T0 here:
    #0 0x4a3662 in malloc ??:0
    #1 0x7fe33fbcc737 in moz_xmalloc firefox/src/memory/mozalloc/mozalloc.cpp:54
    #2 0x7fe333280083 in NS_Alloc_P firefox/src/xpcom/base/nsMemoryImpl.cpp:163
    #3 0x7fe326c9b033 in nsMemory::Alloc(unsigned long) firefox/src/../../../dist/include/nsMemory.h:36
    #4 0x7fe32a1fd170 in nsTextFragment::Append(unsigned short const*, unsigned int, bool) firefox/src/content/base/src/nsTextFragment.cpp:382
    #5 0x7fe329f3deb7 in nsGenericDOMDataNode::SetTextInternal(unsigned int, unsigned int, unsigned short const*, unsigned int, bool, CharacterDataChangeInfo::Details*) firefox/src/content/base/src/nsGenericDOMDataNode.cpp:312
    #6 0x7fe329f4ccbc in nsGenericDOMDataNode::AppendText(unsigned short const*, unsigned int, bool) firefox/src/content/base/src/nsGenericDOMDataNode.cpp:858
    #7 0x7fe32d0dd860 in nsHtml5TreeOperation::AppendTextToTextNode(unsigned short const*, unsigned int, nsIContent*, nsHtml5TreeOpExecutor*) firefox/src/parser/html/nsHtml5TreeOperation.cpp:140
    #8 0x7fe32d0dee80 in nsHtml5TreeOperation::AppendText(unsigned short const*, unsigned int, nsIContent*, nsHtml5TreeOpExecutor*) firefox/src/parser/html/nsHtml5TreeOperation.cpp:155
    #9 0x7fe32d0e8c5f in nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor*, nsIContent**) firefox/src/parser/html/nsHtml5TreeOperation.cpp:451
    #10 0x7fe32d107856 in nsHtml5TreeOpExecutor::RunFlushLoop() firefox/src/parser/html/nsHtml5TreeOpExecutor.cpp:564
    #11 0x7fe32d117065 in nsHtml5ExecutorReflusher::Run() firefox/src/parser/html/nsHtml5TreeOpExecutor.cpp:63
    #12 0x7fe3331ff2c3 in nsThread::ProcessNextEvent(bool, bool*) firefox/src/xpcom/threads/nsThread.cpp:625
    #13 0x7fe332e8e8dd in NS_ProcessNextEvent_P(nsIThread*, bool) firefox/src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #14 0x7fe331ff4ee6 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) firefox/src/ipc/glue/MessagePump.cpp:82
    #15 0x7fe3334afcda in MessageLoop::RunInternal() firefox/src/ipc/chromium/src/base/message_loop.cc:209
    #16 0x7fe3334afb23 in MessageLoop::RunHandler() firefox/src/ipc/chromium/src/base/message_loop.cc:202
    #17 0x7fe3334afa08 in MessageLoop::Run() firefox/src/ipc/chromium/src/base/message_loop.cc:176
    #18 0x7fe33152352e in nsBaseAppShell::Run() firefox/src/widget/xpwidgets/nsBaseAppShell.cpp:165
    #19 0x7fe33016b098 in nsAppStartup::Run() firefox/src/toolkit/components/startup/nsAppStartup.cpp:256
    #20 0x7fe326b3ee17 in XREMain::XRE_mainRun() firefox/src/toolkit/xre/nsAppRunner.cpp:3785
    #21 0x7fe326b457d2 in XREMain::XRE_main(int, char**, nsXREAppData const*) firefox/src/toolkit/xre/nsAppRunner.cpp:3862
    #22 0x7fe326b48c8b in XRE_main firefox/src/toolkit/xre/nsAppRunner.cpp:3938
==27356== ABORTING
Stats: 154M malloced (167M for red zones) by 355141 calls
Stats: 44M realloced by 19866 calls
Stats: 114M freed by 225726 calls
Stats: 0M really freed by 0 calls
Stats: 352M (90162 full pages) mmaped in 88 calls
  mmaps   by size class: 8:278511; 9:57337; 10:20475; 11:18423; 12:3072; 13:2048; 14:1536; 15:384; 16:576; 17:128; 18:160; 19:56; 20:16;
  mallocs by size class: 8:265584; 9:48356; 10:17023; 11:17025; 12:2568; 13:1904; 14:1480; 15:341; 16:526; 17:112; 18:159; 19:49; 20:14;
  frees   by size class: 8:155781; 9:37742; 10:13552; 11:13792; 12:1632; 13:994; 14:1281; 15:284; 16:456; 17:98; 18:57; 19:46; 20:11;
  rfrees  by size class:
Stats: malloc large: 334 small slow: 1873
Shadow byte and word:
  0x1ffc5f5dc5f0: 2
  0x1ffc5f5dc5f0: 02 fb fb fb fb fb fb fb
More shadow bytes:
  0x1ffc5f5dc5d0: fd fd fd fd fd fd fd fd
  0x1ffc5f5dc5d8: fd fd fd fd fd fd fd fd
  0x1ffc5f5dc5e0: fa fa fa fa fa fa fa fa
  0x1ffc5f5dc5e8: fa fa fa fa fa fa fa fa
=>0x1ffc5f5dc5f0: 02 fb fb fb fb fb fb fb
  0x1ffc5f5dc5f8: fb fb fb fb fb fb fb fb
  0x1ffc5f5dc600: fa fa fa fa fa fa fa fa
  0x1ffc5f5dc608: fa fa fa fa fa fa fa fa
  0x1ffc5f5dc610: 00 00 00 00 00 00 00 00
Comment 1 Abhishek Arya 2012-06-17 14:48:11 PDT
Created attachment 633925 [details]
Better testcase, more reliable.
Comment 2 Daniel Veditz [:dveditz] 2012-07-11 11:01:44 PDT
Is an overread in a text string (based on the asan log) a problem in this context, or just possibly slurping too much into the display. Of course the underlying issue could cause worse problems in other contexts, won't know until we find it.
Comment 3 :Ehsan Akhgari (busy, don't ask for review please) 2012-07-11 13:55:06 PDT
(In reply to Daniel Veditz [:dveditz] from comment #2)
> Is an overread in a text string (based on the asan log) a problem in this
> context, or just possibly slurping too much into the display. Of course the
> underlying issue could cause worse problems in other contexts, won't know
> until we find it.

I'm not sure if I grok the question!  :-)
Comment 4 Mats Palmgren (:mats) 2012-07-11 17:37:17 PDT
Created attachment 641286 [details]
stack for "ASSERTION: aPrevFrame must be the last continuation in its chain!"

There's a few assertions leading up to the ASAN exception:

###!!! ASSERTION: aPrevFrame must be the last continuation in its chain!: '!aPrevFrame || (!aPrevFrame->GetNextContinuation() || (aPrevFrame->GetNextContinuation()->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) && !(aPrevFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)', file layout/base/nsFrameManager.cpp, line 456
###!!! ASSERTION: Range out of bounds: 'IsInBounds(mStart, mLength, aStart, aLength)', file layout/generic/nsTextFrameThebes.cpp, line 2812
###!!! ASSERTION: No text for IsSpace!: 'aPos < aFrag->GetLength()', file layout/generic/nsTextFrameThebes.cpp, line 639
###!!! ASSERTION: bad index: 'PRUint32(aIndex) < mState.mLength', file layout/base/../../content/base/src/nsTextFragment.h, line 177

This is the stack for the first assertion.
Comment 5 :Ehsan Akhgari (busy, don't ask for review please) 2012-07-11 21:31:57 PDT
(In reply to Mats Palmgren [:mats] from comment #4)
> Created attachment 641286 [details]
> stack for "ASSERTION: aPrevFrame must be the last continuation in its chain!"
> 
> There's a few assertions leading up to the ASAN exception:
> 
> ###!!! ASSERTION: aPrevFrame must be the last continuation in its chain!:
> '!aPrevFrame || (!aPrevFrame->GetNextContinuation() ||
> (aPrevFrame->GetNextContinuation()->GetStateBits() &
> NS_FRAME_IS_OVERFLOW_CONTAINER)) && !(aPrevFrame->GetStateBits() &
> NS_FRAME_IS_OVERFLOW_CONTAINER)', file layout/base/nsFrameManager.cpp, line
> 456
> ###!!! ASSERTION: Range out of bounds: 'IsInBounds(mStart, mLength, aStart,
> aLength)', file layout/generic/nsTextFrameThebes.cpp, line 2812
> ###!!! ASSERTION: No text for IsSpace!: 'aPos < aFrag->GetLength()', file
> layout/generic/nsTextFrameThebes.cpp, line 639
> ###!!! ASSERTION: bad index: 'PRUint32(aIndex) < mState.mLength', file
> layout/base/../../content/base/src/nsTextFragment.h, line 177
> 
> This is the stack for the first assertion.

Hmm, that doesn't look good at all.  The bug as filed might in fact be the side-effect of something very bad happening here.  Mats, can you take this?  Or jfkthame perhaps?
Comment 6 Al Billings [:abillings] 2012-07-19 13:23:20 PDT
Assigning to Mats but feel free to reassign as necessary (Critsmash triage).
Comment 7 Abhishek Arya 2012-07-25 22:25:50 PDT
Created attachment 646032 [details]
Testcase

Another testcase, looks similar, but feel free to split if it turns out to be different.

=================================================================
==20825== ERROR: AddressSanitizer heap-buffer-overflow on address 0x7f892366f763 at pc 0x7f8908745bc1 bp 0x7fff26ee99d0 sp 0x7fff26ee99c8
READ of size 1 at 0x7f892366f763 thread T0
    #0 0x7f8908745bc1 in nsTextFragment::CharAt(int) const asn1cmn.c:0
    #1 0x7f8909276bf6 in IsCSSWordSpacingSpace(nsTextFragment const*, unsigned int, nsStyleText const*) src/layout/generic/nsTextFrameThebes.cpp:641
    #2 0x7f890927446f in PropertyProvider::GetSpacingInternal(unsigned int, unsigned int, gfxFont::Spacing*, bool) src/layout/generic/nsTextFrameThebes.cpp:2838
    #3 0x7f8909277f33 in PropertyProvider::CalcTabWidths(unsigned int, unsigned int) src/layout/generic/nsTextFrameThebes.cpp:2968
    #4 0x7f89092748b3 in PropertyProvider::GetSpacingInternal(unsigned int, unsigned int, gfxFont::Spacing*, bool) src/layout/generic/nsTextFrameThebes.cpp:2858
    #5 0x7f890927366d in PropertyProvider::GetSpacing(unsigned int, unsigned int, gfxFont::Spacing*) src/layout/generic/nsTextFrameThebes.cpp:2797
    #6 0x7f89141e4603 in GetAdjustedSpacing(gfxTextRun*, unsigned int, unsigned int, gfxTextRun::PropertyProvider*, gfxFont::Spacing*) src/gfx/thebes/gfxFont.cpp:4528
    #7 0x7f89141e318c in gfxTextRun::GetAdjustedSpacingArray(unsigned int, unsigned int, gfxTextRun::PropertyProvider*, unsigned int, unsigned int, nsTArray<gfxFont::Spacing, nsTArrayDefaultAllocator>*) src/gfx/thebes/gfxFont.cpp:4543
    #8 0x7f89141ed60d in gfxTextRun::AccumulateMetricsForRun(gfxFont*, unsigned int, unsigned int, gfxFont::BoundingBoxType, gfxContext*, gfxTextRun::PropertyProvider*, unsigned int, unsigned int, gfxFont::RunMetrics*) src/gfx/thebes/gfxFont.cpp:4790
    #9 0x7f89141eaf97 in gfxTextRun::MeasureText(unsigned int, unsigned int, gfxFont::BoundingBoxType, gfxContext*, gfxTextRun::PropertyProvider*) src/gfx/thebes/gfxFont.cpp:4866
    #10 0x7f89092e8393 in nsTextFrame::ComputeTightBounds(gfxContext*) const src/layout/generic/nsTextFrameThebes.cpp:6936
    #11 0x7f8908ee0cc1 in nsFrame::ComputeSimpleTightBounds(gfxContext*) const src/layout/generic/nsFrame.cpp:3972
    #12 0x7f8908d681aa in nsBlockFrame::ComputeTightBounds(gfxContext*) const src/layout/generic/nsBlockFrame.cpp:861
    #13 0x7f8909f07ebf in nsMathMLContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/mathml/nsMathMLContainerFrame.cpp:895
    #14 0x7f8909f0925e in nsMathMLContainerFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/mathml/nsMathMLContainerFrame.cpp:925
    #15 0x7f89091009bf in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) src/layout/generic/nsLineLayout.cpp:822
    #16 0x7f8908db63bf in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) src/layout/generic/nsBlockFrame.cpp:3830
    #17 0x7f8908dafe1a in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) src/layout/generic/nsBlockFrame.cpp:3626
    #18 0x7f8908da2897 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) src/layout/generic/nsBlockFrame.cpp:3478
    #19 0x7f8908d9124c in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) src/layout/generic/nsBlockFrame.cpp:2566
    #20 0x7f8908d76771 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) src/layout/generic/nsBlockFrame.cpp:2016
    #21 0x7f8908d69b7f in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/generic/nsBlockFrame.cpp:1070
    #22 0x7f8908e59f47 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) src/layout/generic/nsContainerFrame.cpp:906
    #23 0x7f890902f3a7 in nsCanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/generic/nsCanvasFrame.cpp:468
    #24 0x7f8908e59f47 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) src/layout/generic/nsContainerFrame.cpp:906
    #25 0x7f8908fa630e in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) src/layout/generic/nsGfxScrollFrame.cpp:519
    #26 0x7f8908fabe3a in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) src/layout/generic/nsGfxScrollFrame.cpp:619
    #27 0x7f8908fb015f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/generic/nsGfxScrollFrame.cpp:860
    #28 0x7f8908e59f47 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) src/layout/generic/nsContainerFrame.cpp:906
    #29 0x7f8909388790 in ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) src/layout/generic/nsViewportFrame.cpp:200
    #30 0x7f8908ad9436 in PresShell::DoReflow(nsIFrame*, bool) src/layout/base/nsPresShell.cpp:7454
    #31 0x7f8908b06e3d in PresShell::ProcessReflowCommands(bool) src/layout/base/nsPresShell.cpp:7595
    #32 0x7f8908b0554d in PresShell::FlushPendingNotifications(mozFlushType) src/layout/base/nsPresShell.cpp:3864
    #33 0x7f8908ba9dbb in nsRefreshDriver::Notify(nsITimer*) src/layout/base/nsRefreshDriver.cpp:396
    #34 0x7f8913bf3056 in nsTimerImpl::Fire() src/xpcom/threads/nsTimerImpl.cpp:477
    #35 0x7f8913bf4bcc in nsTimerEvent::Run() src/xpcom/threads/nsTimerImpl.cpp:558
    #36 0x7f8913bb71fd in nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:625
    #37 0x7f8913845fad in NS_ProcessNextEvent_P(nsIThread*, bool) src/objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #38 0x7f891084a866 in nsXULWindow::ShowModal() src/xpfe/appshell/src/nsXULWindow.cpp:379
    #39 0x7f891082d302 in nsContentTreeOwner::ShowAsModal() src/xpfe/appshell/src/nsContentTreeOwner.cpp:529
    #40 0x7f891082d47c in non-virtual thunk to nsContentTreeOwner::ShowAsModal() asn1cmn.c:0
    #41 0x7f891065588b in nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow*, char const*, char const*, char const*, bool, nsIArray*, bool, nsIDOMWindow**) src/embedding/components/windowwatcher/src/nsWindowWatcher.cpp:996
    #42 0x7f891064bf11 in nsWindowWatcher::OpenWindow(nsIDOMWindow*, char const*, char const*, char const*, nsISupports*, nsIDOMWindow**) src/embedding/components/windowwatcher/src/nsWindowWatcher.cpp:381
    #43 0x7f8913cb64ca in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
    #44 0x7f890f2c26eb in CallMethodHelper::Call() src/js/xpconnect/src/XPCWrappedNative.cpp:2416
    #45 0x7f890f329a74 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1474
    #46 0x7f891a853cc7 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:382
    #47 0x7f891a7c79a1 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2424
    #48 0x7f891a747ae5 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:302
    #49 0x7f891a8540e9 in js::InvokeKernel(JSContext*, JS::CallArgs, js::MaybeConstruct) src/js/src/jsinterp.cpp:356
    #50 0x7f891a17c890 in js::Invoke(JSContext*, js::InvokeArgsGuard&, js::MaybeConstruct) src/js/src/jsinterp.h:119
    #51 0x7f891a85924d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) src/js/src/jsinterp.cpp:388
    #52 0x7f891a024a49 in JS_CallFunctionValue src/js/src/jsapi.cpp:5569
    #53 0x7f890f271abe in nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) src/js/xpconnect/src/XPCWrappedJSClass.cpp:1436
    #54 0x7f890f2179b8 in nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) src/js/xpconnect/src/XPCWrappedJS.cpp:580
    #55 0x7f8913cbc080 in PrepareAndDispatch src/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:121
    #56 0x7f8913cb9817 in SharedStub src/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:0
    #57 0x7f8913cb64ca in NS_InvokeByIndex_P src/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
    #58 0x7f890f2c26eb in CallMethodHelper::Call() src/js/xpconnect/src/XPCWrappedNative.cpp:2416
    #59 0x7f890f329a74 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) src/js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1474
    #60 0x7f891a853cc7 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:382
    #61 0x7f891a7c79a1 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2424
    #62 0x7f891a747ae5 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:302
    #63 0x7f891a8540e9 in js::InvokeKernel(JSContext*, JS::CallArgs, js::MaybeConstruct) src/js/src/jsinterp.cpp:356
0x7f892366f763 is located 29 bytes to the left of 94-byte region [0x7f892366f780,0x7f892366f7de)
allocated by thread T0 here:
    #0 0x4a4452 in __interceptor_malloc ??:0
    #1 0x7f8920bdf717 in moz_xmalloc src/memory/mozalloc/mozalloc.cpp:54
    #2 0x7f8913c38343 in NS_Alloc_P src/xpcom/base/nsMemoryImpl.cpp:163
    #3 0x7f89071dbb63 in nsMemory::Alloc(unsigned long) src/../../../dist/include/nsMemory.h:36
    #4 0x7f890a7d00eb in nsTextFragment::SetTo(unsigned short const*, int, bool) src/content/base/src/nsTextFragment.cpp:264
    #5 0x7f890a513c33 in nsGenericDOMDataNode::SetTextInternal(unsigned int, unsigned int, unsigned short const*, unsigned int, bool, CharacterDataChangeInfo::Details*) src/content/base/src/nsGenericDOMDataNode.cpp:308
    #6 0x7f890a5227d9 in nsGenericDOMDataNode::SetText(unsigned short const*, unsigned int, bool) src/content/base/src/nsGenericDOMDataNode.cpp:850
    #7 0x7f8908670cc5 in nsIContent::SetText(nsAString_internal const&, bool) src/../../../../dist/include/nsIContent.h:523
    #8 0x7f890a35e82c in nsDocument::CreateTextNode(nsAString_internal const&, nsIContent**) src/content/base/src/nsDocument.cpp:4429
    #9 0x7f890f42ea54 in nsIDOMDocument_CreateTextNode(JSContext*, unsigned int, JS::Value*) src/objdir-ff-asan-sym/js/xpconnect/src/dom_quickstubs.cpp:3322
    #10 0x7f891a853cc7 in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) src/js/src/jscntxtinlines.h:382
    #11 0x7f891a7c79a1 in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) src/js/src/jsinterp.cpp:2424
    #12 0x7f891a747ae5 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) src/js/src/jsinterp.cpp:302
    #13 0x7f891a8540e9 in js::InvokeKernel(JSContext*, JS::CallArgs, js::MaybeConstruct) src/js/src/jsinterp.cpp:356
    #14 0x7f891a17c890 in js::Invoke(JSContext*, js::InvokeArgsGuard&, js::MaybeConstruct) src/js/src/jsinterp.h:119
    #15 0x7f891a85924d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) src/js/src/jsinterp.cpp:388
    #16 0x7f891a024a49 in JS_CallFunctionValue src/js/src/jsapi.cpp:5569
    #17 0x7f890f271abe in nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) src/js/xpconnect/src/XPCWrappedJSClass.cpp:1436
    #18 0x7f890f2179b8 in nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) src/js/xpconnect/src/XPCWrappedJS.cpp:580
    #19 0x7f8913cbc080 in PrepareAndDispatch src/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:121
    #20 0x7f8913cb9817 in SharedStub src/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:0
    #21 0x7f890b0bd7b3 in nsEventListenerManager::HandleEventSubType(nsListenerStruct*, nsIDOMEventListener*, nsIDOMEvent*, nsIDOMEventTarget*, unsigned int, nsCxPusher*) src/content/events/src/nsEventListenerManager.cpp:794
    #22 0x7f890b0bec7a in nsEventListenerManager::HandleEventInternal(nsPresContext*, nsEvent*, nsIDOMEvent**, nsIDOMEventTarget*, unsigned int, nsEventStatus*, nsCxPusher*) src/content/events/src/nsEventListenerManager.cpp:867
    #23 0x7f890b25ab67 in nsEventListenerManager::HandleEvent(nsPresContext*, nsEvent*, nsIDOMEvent**, nsIDOMEventTarget*, unsigned int, nsEventStatus*, nsCxPusher*) src/content/events/src/nsEventListenerManager.h:144
    #24 0x7f890b249806 in nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor&, unsigned int, bool, nsCxPusher*) src/content/events/src/nsEventDispatcher.cpp:184
==20825== ABORTING
Stats: 204M malloced (203M for red zones) by 419604 calls
Stats: 79M realloced by 21269 calls
Stats: 157M freed by 278952 calls
Stats: 24M really freed by 42357 calls
Stats: 416M (106560 full pages) mmaped in 104 calls
  mmaps   by size class: 8:311277; 9:57337; 10:20475; 11:18423; 12:3072; 13:2048; 14:1536; 15:384; 16:576; 17:128; 18:176; 19:112; 20:40;
  mallocs by size class: 8:324925; 9:51704; 10:17898; 11:17545; 12:2679; 13:1992; 14:1491; 15:292; 16:609; 17:135; 18:187; 19:110; 20:37;
  frees   by size class: 8:202445; 9:42553; 10:14293; 11:14511; 12:1758; 13:1054; 14:1277; 15:234; 16:507; 17:106; 18:80; 19:101; 20:33;
  rfrees  by size class: 8:35516; 9:2261; 10:1696; 11:2307; 12:121; 13:208; 14:127; 15:28; 16:35; 17:17; 18:21; 19:8; 20:12;
Stats: malloc large: 469 small slow: 2059
Shadow byte and word:
  0x1ff1246cdeec: fa
  0x1ff1246cdee8: fa fa fa fa fa fa fa fa
More shadow bytes:
  0x1ff1246cdec8: fa fa fa fa fa fa fa fa
  0x1ff1246cded0: fd fd fd fd fd fd fd fd
  0x1ff1246cded8: fd fd fd fd fd fd fd fd
  0x1ff1246cdee0: fa fa fa fa fa fa fa fa
=>0x1ff1246cdee8: fa fa fa fa fa fa fa fa
  0x1ff1246cdef0: 00 00 00 00 00 00 00 00
  0x1ff1246cdef8: 00 00 00 06 fb fb fb fb
  0x1ff1246cdf00: fa fa fa fa fa fa fa fa
  0x1ff1246cdf08: fa fa fa fa fa fa fa fa
Comment 8 Daniel Veditz [:dveditz] 2012-08-02 13:23:19 PDT
qawanted: The assertions happen in non-asan debug builds, so we need to test Fx 15 and ESR-10 to see if they are affected.
Comment 9 Andrew McCreight [:mccr8] 2012-08-02 13:24:48 PDT
esr10 debug build produces the same assertions, so I'm assuming everything is affected.

###!!! ASSERTION: Range out of bounds: 'IsInBounds(mStart, mLength, aStart, aLength)', file /Users/amccreight/mz/esr10/layout/generic/nsTextFrameThebes.cpp, line 2664

over and over.
Comment 10 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-08-09 13:26:25 PDT
RE qawanted, do we have Firefox 15 and ESR10 ASAN builds I can use to test this?
Comment 12 Daniel Veditz [:dveditz] 2012-09-10 15:18:47 PDT
(In reply to Anthony Hughes, Mozilla QA (:ashughes) from comment #10)
> RE qawanted, do we have Firefox 15 and ESR10 ASAN builds I can use to test
> this?

The assertions happen in non-ASan plain debug builds, so this can be tested/verified without ASan builds.

Not convinced this is exploitable yet: we're reading beyond the end of a string in order to find its display length during reflow. By itself that may not be too bad (maybe we'll crash if we read too far). But if we're confused about the buffer's length in some fundamental way maybe a different testcase could get us to write into the incorrect buffer.
Comment 13 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-09-11 15:30:10 PDT
Does comment 9 address the QAWANTED request or is there more needed here?
Comment 14 Mats Palmgren (:mats) 2012-09-11 17:01:02 PDT
No additional QA is needed at this point, this bug affects all branches.
I think I understand the issue now.
Comment 15 Mats Palmgren (:mats) 2012-09-11 17:26:05 PDT
Created attachment 660269 [details]
stack + frame dump for "ASSERTION: aPrevFrame must be the last continuation in its chain!"

The problem starts already during frame construction where we append
frames in the middle of a continuation chain.

FindAppendPrevSibling() in nsCSSFrameConstructor.cpp does this:
  aParentFrame->GetLastChild(kPrincipalList);

it doesn't consider there could be an overflow list from an earlier
reflow (interrupted, I assume).
Comment 16 Mats Palmgren (:mats) 2012-09-11 17:33:41 PDT
Created attachment 660274 [details] [diff] [review]
wip

I guess we could make FindAppendPrevSibling (and frame construction
in general) consider the overflow list, but perhaps it would be simpler
and more robust to eliminate the overflow frames by moving them to the
end of the principal list before attempting any frame tree insertions.
Would this work?
Comment 18 Boris Zbarsky [:bz] 2012-09-12 14:16:32 PDT
Draining the overflow list before doing insertions makes sense to me.  Mats, are you planning to work on this?  It looks like you unassigned from self, but that might have been a side effect of the component change...
Comment 19 Mats Palmgren (:mats) 2012-09-12 14:47:38 PDT
Oops, I cleared it by mistake.  OK, I'll go ahead with that patch then...
I just need to check if there are more places in nsCSSFrameConstructor
that needs a DrainOverflowList() call.  (and I'll probably rename it
since there are other DrainOverflow* methods already and they drain both
the prev-in-flow and self)
Comment 20 Daniel Veditz [:dveditz] 2012-09-13 13:41:48 PDT
The sooner this can land and get some testing the better since we'd like to uplift this to Firefox 16 which is fast approaching.
Comment 21 Mats Palmgren (:mats) 2012-09-14 07:29:21 PDT
Created attachment 661217 [details] [diff] [review]
fix

Spawn out the latter part of nsBlockFrame::DrainOverflowLines and
nsContainerFrame::MoveOverflowToChildList into new methods named
DrainSelfOverflowList and make the frame ctor call it before
attempting to insert new frames.

https://tbpl.mozilla.org/?tree=Try&rev=3df24de39a60
Comment 22 Boris Zbarsky [:bz] 2012-09-16 11:52:38 PDT
Comment on attachment 661217 [details] [diff] [review]
fix

>+++ b/layout/generic/nsBlockFrame.cpp
>+  bool didFindOverflow = false;

Maybe "didFindOverflowFromPrevContinuation"?

Either way, I guess.

r=me
Comment 24 Al Billings [:abillings] 2012-09-17 15:10:34 PDT
Bounty Awarded $3000
Comment 26 :Ehsan Akhgari (busy, don't ask for review please) 2012-09-18 05:35:12 PDT
http://hg.mozilla.org/mozilla-central/rev/e016faeb6b15
Comment 27 Alex Keybl [:akeybl] 2012-09-19 17:36:04 PDT
If we think this is low risk enough to uplift into FF16, please nominate for aurora/beta approval prior to Tuesday's Beta 5 go to build. If not, we'll untrack for release.
Comment 28 Mats Palmgren (:mats) 2012-09-19 18:03:43 PDT
Comment on attachment 661217 [details] [diff] [review]
fix

[Approval Request Comment]
Bug caused by (feature/regressing bug #): 
User impact if declined: possibly exploitable crash
Testing completed (on m-c, etc.): on m-c since 2012-09-18
Risk to taking this patch (and alternatives if risky): low, the only real change is the added DrainSelfOverflowList() calls in nsCSSFrameConstructor.cpp which *should* be safe to do, the rest is just re-shuffling of existing code.
String or UUID changes made by this patch: none
Comment 29 Alex Keybl [:akeybl] 2012-09-20 15:42:08 PDT
Comment on attachment 661217 [details] [diff] [review]
fix

[Triage Comment]
Approving for Aurora in preparation for Beta consideration.
Comment 31 Alex Keybl [:akeybl] 2012-09-24 15:25:58 PDT
Comment on attachment 661217 [details] [diff] [review]
fix

[Triage Comment]
Low risk fix for a sec-critical bug, and we've got some time to still find regressions before release. Approving for Beta.

Please also prepare an ESR10 fix.
Comment 32 Mats Palmgren (:mats) 2012-09-24 16:35:57 PDT
https://hg.mozilla.org/releases/mozilla-beta/rev/e97453246c7d
Comment 33 Mats Palmgren (:mats) 2012-09-24 22:19:36 PDT
Created attachment 664359 [details] [diff] [review]
ported to esr branch

The beta-branch patch applied cleanly except for nsBlockFrame.cpp
which I had to change manually.  Please re-review that file.
(fwiw, crashtests/reftests pass locally)
Comment 34 Boris Zbarsky [:bz] 2012-09-25 13:22:26 PDT
Comment on attachment 664359 [details] [diff] [review]
ported to esr branch

r=me
Comment 35 Mats Palmgren (:mats) 2012-09-26 08:30:56 PDT
Comment on attachment 664359 [details] [diff] [review]
ported to esr branch

[Approval Request Comment]
same as comment 28
Comment 39 Mats Palmgren (:mats) 2013-05-14 07:00:38 PDT
Crash test:
https://hg.mozilla.org/integration/mozilla-inbound/rev/91eca1cb35ac
Comment 40 Ryan VanderMeulen [:RyanVM] 2013-05-14 13:29:54 PDT
https://hg.mozilla.org/mozilla-central/rev/91eca1cb35ac
Comment 41 Tracy Walker [:tracy] 2014-01-10 10:42:17 PST
mass remove verifyme requests greater than 4 months old

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