Last Comment Bug 769120 - (CVE-2012-3962) Bad iterator in text runs
(CVE-2012-3962)
: Bad iterator in text runs
Status: VERIFIED FIXED
[asan][advisory-tracking+][qa-]
: crash, sec-high, testcase
Product: Core
Classification: Components
Component: Layout: Text (show other bugs)
: Trunk
: x86_64 All
: -- critical (vote)
: mozilla17
Assigned To: Mats Palmgren (vacation)
: Anthony Hughes (:ashughes) [GFX][QA][Mentor]
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-06-27 18:37 PDT by Abhishek Arya
Modified: 2014-07-24 13:44 PDT (History)
7 users (show)
dchanm+bugzilla: sec‑bounty+
mats: in‑testsuite+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
wontfix
+
fixed
+
verified
verified
15+
fixed


Attachments
Testcase (604 bytes, text/html)
2012-06-27 18:37 PDT, Abhishek Arya
no flags Details
frame dump + stack for the assertion (17.15 KB, text/html)
2012-07-12 07:43 PDT, Mats Palmgren (vacation)
no flags Details
fix (752 bytes, patch)
2012-07-12 07:48 PDT, Mats Palmgren (vacation)
no flags Details | Diff | Splinter Review
fix, v2 (1.01 KB, patch)
2012-07-25 12:23 PDT, Mats Palmgren (vacation)
roc: review+
lukasblakk+bugs: approval‑mozilla‑aurora+
lukasblakk+bugs: approval‑mozilla‑beta+
lukasblakk+bugs: approval‑mozilla‑esr10+
Details | Diff | Splinter Review

Description Abhishek Arya 2012-06-27 18:37:04 PDT
Created attachment 637336 [details]
Testcase

Reproduces on trunk. The backIterator's line looks to be pointing to bad address.

    nsBlockFrame::line_iterator line = backIterator.GetLine();
    if (!backIterator.Prev() || backIterator.GetLine()->IsBlock()) {

ASAN:SIGSEGV
==15447== ERROR: AddressSanitizer crashed on unknown address 0x120000000006 (pc 0x7fa9f3a027e9 sp 0x7fff4ca846a0 bp 0x7fff4ca84770 T0)
AddressSanitizer can not provide additional info. ABORTING
    #0 0x7fa9f3a027e9 in nsLineBox::IsBlock() const layout/base/../generic/nsLineBox.h:225
    #1 0x7fa9f426075d in BuildTextRuns(gfxContext*, nsTextFrame*, nsIFrame*, nsLineList_iterator const*, nsTextFrame::TextRunType) layout/generic/nsTextFrameThebes.cpp:1220
    #2 0x7fa9f425d1a4 in nsTextFrame::EnsureTextRun(nsTextFrame::TextRunType, gfxContext*, nsIFrame*, nsLineList_iterator const*, unsigned int*) layout/generic/nsTextFrameThebes.cpp:2391
    #3 0x7fa9f42cf6c8 in nsTextFrame::AddInlineMinWidthForFlow(nsRenderingContext*, nsIFrame::InlineMinWidthData*, nsTextFrame::TextRunType) layout/generic/nsTextFrameThebes.cpp:6594
    #4 0x7fa9f42d65c8 in nsTextFrame::AddInlineMinWidth(nsRenderingContext*, nsIFrame::InlineMinWidthData*) layout/generic/nsTextFrameThebes.cpp:6746
    #5 0x7fa9f3e50bf5 in nsContainerFrame::DoInlineIntrinsicWidth(nsRenderingContext*, nsIFrame::InlineIntrinsicWidthData*, nsLayoutUtils::IntrinsicWidthType) layout/generic/nsContainerFrame.cpp:813
    #6 0x7fa9f3e63b06 in nsFirstLetterFrame::AddInlineMinWidth(nsRenderingContext*, nsIFrame::InlineMinWidthData*) layout/generic/nsFirstLetterFrame.cpp:122
    #7 0x7fa9f39f8a1b in nsLayoutUtils::MinWidthFromInline(nsIFrame*, nsRenderingContext*) layout/base/nsLayoutUtils.cpp:3009
    #8 0x7fa9f3e63f38 in nsFirstLetterFrame::GetMinWidth(nsRenderingContext*) layout/generic/nsFirstLetterFrame.cpp:137
    #9 0x7fa9f3ed9595 in nsFrame::ShrinkWidthToFit(nsRenderingContext*, int) layout/generic/nsFrame.cpp:3935
    #10 0x7fa9f3e5270a in nsContainerFrame::ComputeAutoSize(nsRenderingContext*, nsSize, int, nsSize, nsSize, nsSize, bool) layout/generic/nsContainerFrame.cpp:860
    #11 0x7fa9f3ed4d8e in nsFrame::ComputeSize(nsRenderingContext*, nsSize, int, nsSize, nsSize, nsSize, unsigned int) layout/generic/nsFrame.cpp:3780
    #12 0x7fa9f3e64c1c in nsFirstLetterFrame::ComputeSize(nsRenderingContext*, nsSize, int, nsSize, nsSize, nsSize, unsigned int) layout/generic/nsFirstLetterFrame.cpp:158
    #13 0x7fa9f3e0780d in FloatMarginWidth(nsHTMLReflowState const&, int, nsIFrame*, nsCSSOffsetState const&) layout/generic/nsBlockReflowState.cpp:562
    #14 0x7fa9f3e00ff2 in nsBlockReflowState::FlowAndPlaceFloat(nsIFrame*) layout/generic/nsBlockReflowState.cpp:608
    #15 0x7fa9f3d6af86 in nsBlockFrame::ReflowPushedFloats(nsBlockReflowState&, nsOverflowAreas&, unsigned int&) layout/generic/nsBlockFrame.cpp:6017
    #16 0x7fa9f3d6390d in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsBlockFrame.cpp:1057
    #17 0x7fa9f3e536a7 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:906
    #18 0x7fa9f3e355b5 in nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&, nsColumnSetFrame::ReflowConfig const&, bool, nsCollapsingMargin*, nsColumnSetFrame::ColumnBalanceData&) layout/generic/nsColumnSetFrame.cpp:665
    #19 0x7fa9f3e3c757 in nsColumnSetFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsColumnSetFrame.cpp:920
    #20 0x7fa9f3df3e3b in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) layout/generic/nsBlockReflowContext.cpp:262
    #21 0x7fa9f3d95137 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:3206
    #22 0x7fa9f3d8a826 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:2514
    #23 0x7fa9f3d73589 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) layout/generic/nsBlockFrame.cpp:2308
    #24 0x7fa9f3d63bcf in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsBlockFrame.cpp:1069
    #25 0x7fa9f3e536a7 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:906
    #26 0x7fa9f3e355b5 in nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&, nsColumnSetFrame::ReflowConfig const&, bool, nsCollapsingMargin*, nsColumnSetFrame::ColumnBalanceData&) layout/generic/nsColumnSetFrame.cpp:665
    #27 0x7fa9f3e3c757 in nsColumnSetFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsColumnSetFrame.cpp:920
    #28 0x7fa9f3e536a7 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:906
    #29 0x7fa9f40239a7 in nsCanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsCanvasFrame.cpp:429
    #30 0x7fa9f3e536a7 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:906
    #31 0x7fa9f3f9d74e in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) layout/generic/nsGfxScrollFrame.cpp:517
    #32 0x7fa9f3fa2ffa in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) layout/generic/nsGfxScrollFrame.cpp:617
    #33 0x7fa9f3fa731f in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsGfxScrollFrame.cpp:858
    #34 0x7fa9f3e536a7 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:906
    #35 0x7fa9f437bea1 in ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsViewportFrame.cpp:200
    #36 0x7fa9f3ad4ca6 in PresShell::DoReflow(nsIFrame*, bool) layout/base/nsPresShell.cpp:7383
    #37 0x7fa9f3b026ad in PresShell::ProcessReflowCommands(bool) layout/base/nsPresShell.cpp:7524
    #38 0x7fa9f3b00dbd in PresShell::FlushPendingNotifications(mozFlushType) layout/base/nsPresShell.cpp:3852
    #39 0x7fa9f3ba3d6b in nsRefreshDriver::Notify(nsITimer*) layout/base/nsRefreshDriver.cpp:396
    #40 0x7fa9fe7af1a6 in nsTimerImpl::Fire() xpcom/threads/nsTimerImpl.cpp:477
    #41 0x7fa9fe7b0d1c in nsTimerEvent::Run() xpcom/threads/nsTimerImpl.cpp:558
    #42 0x7fa9fe7733d3 in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:625
    #43 0x7fa9fe40242d in NS_ProcessNextEvent_P(nsIThread*, bool) objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:217
    #44 0x7fa9fb5fe026 in nsXULWindow::ShowModal() xpfe/appshell/src/nsXULWindow.cpp:378
    #45 0x7fa9fb5e0fa2 in nsContentTreeOwner::ShowAsModal() xpfe/appshell/src/nsContentTreeOwner.cpp:529
    #46 0x7fa9fb5e111c in non-virtual thunk to nsContentTreeOwner::ShowAsModal() modules/zlib/src/inffast.c:0
    #47 0x7fa9fb409574 in nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow*, char const*, char const*, char const*, bool, nsIArray*, bool, nsIDOMWindow**) embedding/components/windowwatcher/src/nsWindowWatcher.cpp:1000
    #48 0x7fa9fb3ffb51 in nsWindowWatcher::OpenWindow(nsIDOMWindow*, char const*, char const*, char const*, nsISupports*, nsIDOMWindow**) embedding/components/windowwatcher/src/nsWindowWatcher.cpp:381
    #49 0x7fa9fe87289a in NS_InvokeByIndex_P xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
    #50 0x7fa9fa1de9db in CallMethodHelper::Call() js/xpconnect/src/XPCWrappedNative.cpp:2405
    #51 0x7fa9fa245db4 in XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1474
    #52 0x7faa03b969dd in js::CallJSNative(JSContext*, int (*)(JSContext*, unsigned int, JS::Value*), js::CallArgs const&) js/src/jscntxtinlines.h:400
    #53 0x7faa03b0abbd in js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) js/src/jsinterp.cpp:2437
    #54 0x7faa03a90397 in js::RunScript(JSContext*, JSScript*, js::StackFrame*) js/src/jsinterp.cpp:267
    #55 0x7faa03b96dff in js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) js/src/jsinterp.cpp:322
    #56 0x7faa03531210 in js::Invoke(JSContext*, js::InvokeArgsGuard&, js::MaybeConstruct) js/src/jsinterp.h:100
    #57 0x7faa03b9bf2d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) js/src/jsinterp.cpp:354
    #58 0x7faa033ddd69 in JS_CallFunctionValue js/src/jsapi.cpp:5499
    #59 0x7fa9fa18dd32 in nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) js/xpconnect/src/XPCWrappedJSClass.cpp:1471
    #60 0x7fa9fa13f6b8 in nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) js/xpconnect/src/XPCWrappedJS.cpp:580
    #61 0x7fa9fe878450 in PrepareAndDispatch xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:121
    #62 0x7fa9fe875be7 in SharedStub xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp:0
    #63 0x7fa9fe87289a in NS_InvokeByIndex_P xpcom/reflect/xptcall/src/md/unix/xptcinvoke_x86_64_unix.cpp:161
Stats: 146M malloced (161M for red zones) by 349338 calls
Stats: 41M realloced by 19068 calls
Stats: 109M freed by 225400 calls
Stats: 0M really freed by 0 calls
Stats: 340M (87088 full pages) mmaped in 85 calls
  mmaps   by size class: 8:278511; 9:49146; 10:20475; 11:18423; 12:3072; 13:2048; 14:1536; 15:384; 16:576; 17:128; 18:160; 19:40; 20:16;
  mallocs by size class: 8:264631; 9:45378; 10:16372; 11:16361; 12:2245; 13:1771; 14:1409; 15:325; 16:527; 17:113; 18:153; 19:40; 20:13;
  frees   by size class: 8:159416; 9:35324; 10:13021; 11:13202; 12:1408; 13:876; 14:1217; 15:274; 16:457; 17:99; 18:58; 19:38; 20:10;
  rfrees  by size class:
Stats: malloc large: 319 small slow: 1810
Comment 1 Daniel Veditz [:dveditz] 2012-07-11 10:44:22 PDT
Related to the other text run bugs? Same underlying bug, or just a generally dodgy bit of code?
Comment 2 Mats Palmgren (vacation) 2012-07-12 07:43:58 PDT
Created attachment 641457 [details]
frame dump + stack for the assertion

The problem appears to be that nsTextFrame::IsFloatingFirstLetterChild()
returns false because the text frame (red) is missing TEXT_FIRST_LETTER,
probably because it's zero-length:
http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#7384

I think we want BuildTextRuns() to find the line container for the
first-letter's placeholder also for this text frame.
http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsTextFrameThebes.cpp#1148
Comment 3 Mats Palmgren (vacation) 2012-07-12 07:48:48 PDT
Created attachment 641461 [details] [diff] [review]
fix

Maybe like so?

https://tbpl.mozilla.org/?tree=Try&rev=42cbbec3c134
Comment 4 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2012-07-12 19:00:30 PDT
Comment on attachment 641461 [details] [diff] [review]
fix

Review of attachment 641461 [details] [diff] [review]:
-----------------------------------------------------------------

Looks reasonable but it's probably slightly more efficient to test IsFloating() first
Comment 5 Mats Palmgren (vacation) 2012-07-25 12:23:12 PDT
Created attachment 645853 [details] [diff] [review]
fix, v2
Comment 7 Ed Morley [:emorley] 2012-07-26 05:16:46 PDT
https://hg.mozilla.org/mozilla-central/rev/b5e5f22f5454
Comment 8 Mats Palmgren (vacation) 2012-07-26 08:33:21 PDT
Comment on attachment 645853 [details] [diff] [review]
fix, v2

Low risk crash fix.
Comment 10 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-08-14 15:18:41 PDT
I'm willing to work on resolving the in-testsuite request provided some mentorship.
Comment 11 Mats Palmgren (vacation) 2012-08-14 17:50:30 PDT
(In reply to Anthony Hughes, Mozilla QA (:ashughes) from comment #10)
> I'm willing to work on resolving the in-testsuite request provided some
> mentorship.

Thanks, but we shouldn't land tests for security sensitive bugs before
the bug report is public.  There's probably backlog of those, so if it's
possible to query for "core-security flag changed from set to unset" and
"in-testsuite?" you could start with those (*).  Please don't land tests that
are marked "private" though (usually because they are not minimized and
reveal fuzz techniques).  For Layout crash bugs, in most cases you can
just land them as is under layout/*/crashtests/ (pick a directory based on
which where most files were fixed).  Please verify that the test crashes
a build without the fix if possible.

(*) Or, resolved bugs with "in-testsuite?" and Severity=critical/blocker.
There's 754 of those under Core that are public.
http://is.gd/IjySVG
Comment 12 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-08-24 15:51:56 PDT
Confirmed reproducible with ASAN build created from changeset 3951ffaf1b9b.

Verified fixed with:
 * 2012-08-23 Firefox 17.0a1 ASAN Debug
 * 2012-08-24 Firefox 16.0a2 ASAN Debug

Marking qa- until we have the means to verify for Beta/Release and ESR ASAN builds.
Comment 14 Mats Palmgren (vacation) 2013-05-14 07:01:41 PDT
Crash test:
https://hg.mozilla.org/integration/mozilla-inbound/rev/ac791df49d0a
Comment 15 Ryan VanderMeulen [:RyanVM] 2013-05-14 13:30:06 PDT
https://hg.mozilla.org/mozilla-central/rev/ac791df49d0a

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