Closed Bug 769120 (CVE-2012-3962) Opened 8 years ago Closed 8 years ago

Bad iterator in text runs

Categories

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

x86_64
All
defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla17
Tracking Status
firefox14 --- wontfix
firefox15 + fixed
firefox16 + verified
firefox17 --- verified
firefox-esr10 15+ fixed

People

(Reporter: inferno, Assigned: mats)

References

Details

(Keywords: crash, sec-high, testcase, Whiteboard: [asan][advisory-tracking+][qa-])

Attachments

(3 files, 1 obsolete file)

Attached file 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
Whiteboard: [asan]
Related to the other text run bugs? Same underlying bug, or just a generally dodgy bit of code?
Component: General → Layout: Text
Keywords: sec-high, testcase
Product: Firefox → Core
See Also: → CVE-2012-4218
Severity: normal → critical
Keywords: crash
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
Attached patch fix (obsolete) — Splinter Review
Maybe like so?

https://tbpl.mozilla.org/?tree=Try&rev=42cbbec3c134
Assignee: nobody → matspal
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
Attached patch fix, v2Splinter Review
Attachment #641461 - Attachment is obsolete: true
Attachment #645853 - Flags: review?(roc)
https://hg.mozilla.org/mozilla-central/rev/b5e5f22f5454
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Comment on attachment 645853 [details] [diff] [review]
fix, v2

Low risk crash fix.
Attachment #645853 - Flags: approval-mozilla-esr10?
Attachment #645853 - Flags: approval-mozilla-beta?
Attachment #645853 - Flags: approval-mozilla-aurora?
Attachment #645853 - Flags: approval-mozilla-esr10?
Attachment #645853 - Flags: approval-mozilla-esr10+
Attachment #645853 - Flags: approval-mozilla-beta?
Attachment #645853 - Flags: approval-mozilla-beta+
Attachment #645853 - Flags: approval-mozilla-aurora?
Attachment #645853 - Flags: approval-mozilla-aurora+
Whiteboard: [asan] → [asan][advisory-tracking+]
I'm willing to work on resolving the in-testsuite request provided some mentorship.
QA Contact: anthony.s.hughes
Whiteboard: [asan][advisory-tracking+] → [asan][advisory-tracking+][qa+]
(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
Keywords: verifyme
Alias: CVE-2012-3962
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.
Status: RESOLVED → VERIFIED
Keywords: verifyme
Whiteboard: [asan][advisory-tracking+][qa+] → [asan][advisory-tracking+][qa-]
Group: core-security
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
Crash test:
https://hg.mozilla.org/integration/mozilla-inbound/rev/ac791df49d0a
Flags: in-testsuite? → in-testsuite+
You need to log in before you can comment on or make changes to this bug.