Closed Bug 1504918 Opened 6 years ago Closed 6 years ago

null pointer derefernce in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *)

Categories

(Core :: SVG, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla65
Tracking Status
firefox63 --- wontfix
firefox64 --- wontfix
firefox65 --- fixed

People

(Reporter: geeknik, Assigned: jwatt)

References

(Depends on 1 open bug)

Details

(Keywords: csectype-nullptr, nightly-community)

Attachments

(3 files, 1 obsolete file)

Attached file fuzz-14.html (obsolete) —
While fuzzing Firefox 65.0a1 (BuildID 20181105100136), I found a crafted HTML which crashes the browser tab.

=================================================================
==8652==ERROR: AddressSanitizer: access-violation on unknown address 0x000000000078 (pc 0x7ff8102ac711 bp 0x00172fdf09f0 sp 0x00172fdf0940 T0)
==8652==The signal is caused by a READ memory access.
==8652==Hint: address points to the zero page.
    #0 0x7ff8102ac710 in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *) z:\build\build\src\layout\svg\SVGTextFrame.cpp:1518
    #1 0x7ff8102ac52a in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *) z:\build\build\src\layout\svg\SVGTextFrame.cpp:1458
    #2 0x7ff8102ac52a in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *) z:\build\build\src\layout\svg\SVGTextFrame.cpp:1458
    #3 0x7ff8102ac52a in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *) z:\build\build\src\layout\svg\SVGTextFrame.cpp:1458
    #4 0x7ff8102ab9eb in mozilla::TextNodeCorrespondenceRecorder::RecordCorrespondence(class SVGTextFrame *) z:\build\build\src\layout\svg\SVGTextFrame.cpp:1399
    #5 0x7ff8102be41c in SVGTextFrame::ReflowSVGNonDisplayText(void) z:\build\build\src\layout\svg\SVGTextFrame.cpp:3288
    #6 0x7ff810303db2 in nsSVGContainerFrame::ReflowSVGNonDisplayText(class nsIFrame *) z:\build\build\src\layout\svg\nsSVGContainerFrame.cpp:122
    #7 0x7ff8102c21c0 in nsSVGDisplayContainerFrame::ReflowSVG(void) z:\build\build\src\layout\svg\nsSVGContainerFrame.cpp:360
    #8 0x7ff81033ef31 in nsSVGOuterSVGFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\svg\nsSVGOuterSVGFrame.cpp:460
    #9 0x7ff81001ec40 in nsLineLayout::ReflowFrame(class nsIFrame *,class nsReflowStatus &,class mozilla::ReflowOutput *,bool &) z:\build\build\src\layout\generic\nsLineLayout.cpp:933
    #10 0x7ff81001cdf5 in nsInlineFrame::ReflowInlineFrame(class nsPresContext *,struct mozilla::ReflowInput const &,struct nsInlineFrame::InlineReflowInput &,class nsIFrame *,class nsReflowStatus &) z:\build\build\src\layout\generic\nsInlineFrame.cpp:729
    #11 0x7ff81001ad00 in nsInlineFrame::ReflowFrames(class nsPresContext *,struct mozilla::ReflowInput const &,struct nsInlineFrame::InlineReflowInput &,class mozilla::ReflowOutput &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsInlineFrame.cpp:598
    #12 0x7ff810019993 in nsInlineFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsInlineFrame.cpp:400
    #13 0x7ff81001ec40 in nsLineLayout::ReflowFrame(class nsIFrame *,class nsReflowStatus &,class mozilla::ReflowOutput *,bool &) z:\build\build\src\layout\generic\nsLineLayout.cpp:933
    #14 0x7ff80fdf185a in nsBlockFrame::ReflowInlineFrame(class mozilla::BlockReflowInput &,class nsLineLayout &,class nsLineList_iterator,class nsIFrame *,enum LineReflowStatus *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:4271
    #15 0x7ff80fdefbff in nsBlockFrame::DoReflowInlineFrames(class mozilla::BlockReflowInput &,class nsLineLayout &,class nsLineList_iterator,struct nsFlowAreaRect &,int &,struct nsFloatManager::SavedState *,bool *,enum LineReflowStatus *,bool) z:\build\build\src\layout\generic\nsBlockFrame.cpp:4071
    #16 0x7ff80fde57a9 in nsBlockFrame::ReflowInlineFrames(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:3944
    #17 0x7ff80fddc1a5 in nsBlockFrame::ReflowLine(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2926
    #18 0x7ff80fdced75 in nsBlockFrame::ReflowDirtyLines(class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2460
    #19 0x7ff80fdc492b in nsBlockFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:1294
    #20 0x7ff80fdecd0c in nsBlockReflowContext::ReflowBlock(class mozilla::LogicalRect const &,bool,struct nsCollapsingMargin &,int,bool,class nsLineBox *,struct mozilla::ReflowInput &,class nsReflowStatus &,class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockReflowContext.cpp:309
    #21 0x7ff80fddebdd in nsBlockFrame::ReflowBlockFrame(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:3573
    #22 0x7ff80fddc350 in nsBlockFrame::ReflowLine(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2923
    #23 0x7ff80fdced75 in nsBlockFrame::ReflowDirtyLines(class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2460
    #24 0x7ff80fdc492b in nsBlockFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:1294
    #25 0x7ff80fdecd0c in nsBlockReflowContext::ReflowBlock(class mozilla::LogicalRect const &,bool,struct nsCollapsingMargin &,int,bool,class nsLineBox *,struct mozilla::ReflowInput &,class nsReflowStatus &,class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockReflowContext.cpp:309
    #26 0x7ff80fddebdd in nsBlockFrame::ReflowBlockFrame(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:3573
    #27 0x7ff80fddc350 in nsBlockFrame::ReflowLine(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2923
    #28 0x7ff80fdced75 in nsBlockFrame::ReflowDirtyLines(class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2460
    #29 0x7ff80fdc492b in nsBlockFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:1294
    #30 0x7ff80fdecd0c in nsBlockReflowContext::ReflowBlock(class mozilla::LogicalRect const &,bool,struct nsCollapsingMargin &,int,bool,class nsLineBox *,struct mozilla::ReflowInput &,class nsReflowStatus &,class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockReflowContext.cpp:309
    #31 0x7ff80fddebdd in nsBlockFrame::ReflowBlockFrame(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:3573
    #32 0x7ff80fddc350 in nsBlockFrame::ReflowLine(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2923
    #33 0x7ff80fdced75 in nsBlockFrame::ReflowDirtyLines(class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2460
    #34 0x7ff80fdc492b in nsBlockFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:1294
    #35 0x7ff80fdecd0c in nsBlockReflowContext::ReflowBlock(class mozilla::LogicalRect const &,bool,struct nsCollapsingMargin &,int,bool,class nsLineBox *,struct mozilla::ReflowInput &,class nsReflowStatus &,class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockReflowContext.cpp:309
    #36 0x7ff80fddebdd in nsBlockFrame::ReflowBlockFrame(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:3573
    #37 0x7ff80fddc350 in nsBlockFrame::ReflowLine(class mozilla::BlockReflowInput &,class nsLineList_iterator,bool *) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2923
    #38 0x7ff80fdced75 in nsBlockFrame::ReflowDirtyLines(class mozilla::BlockReflowInput &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:2460
    #39 0x7ff80fdc492b in nsBlockFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsBlockFrame.cpp:1294
    #40 0x7ff80fe395e4 in nsContainerFrame::ReflowChild(class nsIFrame *,class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class mozilla::WritingMode const &,class mozilla::LogicalPoint const &,struct nsSize const &,unsigned int,class nsReflowStatus &,class nsOverflowContinuationTracker *) z:\build\build\src\layout\generic\nsContainerFrame.cpp:951
    #41 0x7ff80fe37600 in nsCanvasFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsCanvasFrame.cpp:803
    #42 0x7ff80fe395e4 in nsContainerFrame::ReflowChild(class nsIFrame *,class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class mozilla::WritingMode const &,class mozilla::LogicalPoint const &,struct nsSize const &,unsigned int,class nsReflowStatus &,class nsOverflowContinuationTracker *) z:\build\build\src\layout\generic\nsContainerFrame.cpp:951
    #43 0x7ff80ff5206c in nsHTMLScrollFrame::ReflowScrolledFrame(struct mozilla::ScrollReflowInput *,bool,bool,class mozilla::ReflowOutput *,bool) z:\build\build\src\layout\generic\nsGfxScrollFrame.cpp:606
    #44 0x7ff80ff53b56 in nsHTMLScrollFrame::ReflowContents(struct mozilla::ScrollReflowInput *,class mozilla::ReflowOutput const &) z:\build\build\src\layout\generic\nsGfxScrollFrame.cpp:730
    #45 0x7ff80ff5844f in nsHTMLScrollFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\nsGfxScrollFrame.cpp:1120
    #46 0x7ff80fda2197 in nsContainerFrame::ReflowChild(class nsIFrame *,class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,int,int,unsigned int,class nsReflowStatus &,class nsOverflowContinuationTracker *) z:\build\build\src\layout\generic\nsContainerFrame.cpp:995
    #47 0x7ff80fda09ba in mozilla::ViewportFrame::Reflow(class nsPresContext *,class mozilla::ReflowOutput &,struct mozilla::ReflowInput const &,class nsReflowStatus &) z:\build\build\src\layout\generic\ViewportFrame.cpp:338
    #48 0x7ff80fb274cc in mozilla::PresShell::DoReflow(class nsIFrame *,bool) z:\build\build\src\layout\base\PresShell.cpp:9057
    #49 0x7ff80fb4016d in mozilla::PresShell::ProcessReflowCommands(bool) z:\build\build\src\layout\base\PresShell.cpp:9230
    #50 0x7ff80fb3e34c in mozilla::PresShell::DoFlushPendingNotifications(struct mozilla::ChangesToFlush) z:\build\build\src\layout\base\PresShell.cpp:4387
    #51 0x7ff80fab75fd in nsRefreshDriver::Tick(class mozilla::TimeStamp) z:\build\build\src\layout\base\nsRefreshDriver.cpp:1932
    #52 0x7ff80facb44e in mozilla::RefreshDriverTimer::TickRefreshDrivers(class mozilla::TimeStamp,class nsTArray<class RefPtr<class nsRefreshDriver> > &) z:\build\build\src\layout\base\nsRefreshDriver.cpp:301
    #53 0x7ff80facb0ae in mozilla::RefreshDriverTimer::Tick(class mozilla::TimeStamp) z:\build\build\src\layout\base\nsRefreshDriver.cpp:319
    #54 0x7ff80face69c in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::TickRefreshDriver(class mozilla::TimeStamp) z:\build\build\src\layout\base\nsRefreshDriver.cpp:676
    #55 0x7ff80facd9be in mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsync(class mozilla::TimeStamp) z:\build\build\src\layout\base\nsRefreshDriver.cpp:573
    #56 0x7ff8104d7bc5 in mozilla::layout::VsyncChild::RecvNotify(class mozilla::TimeStamp const &) z:\build\build\src\layout\ipc\VsyncChild.cpp:76
    #57 0x7ff806c36577 in mozilla::layout::PVsyncChild::OnMessageReceived(class IPC::Message const &) z:\build\build\src\obj-firefox\ipc\ipdl\PVsyncChild.cpp:167
    #58 0x7ff806a7a68f in mozilla::ipc::PBackgroundChild::OnMessageReceived(class IPC::Message const &) z:\build\build\src\obj-firefox\ipc\ipdl\PBackgroundChild.cpp:2280
    #59 0x7ff8065185e2 in mozilla::ipc::MessageChannel::DispatchAsyncMessage(class IPC::Message const &) z:\build\build\src\ipc\glue\MessageChannel.cpp:2255
    #60 0x7ff806515050 in ?DispatchMessageW@MessageChannel@ipc@mozilla@@AEAAX$$QEAVMessage@IPC@@@Z z:\build\build\src\ipc\glue\MessageChannel.cpp:2182
    #61 0x7ff806516c9f in mozilla::ipc::MessageChannel::RunMessage(class mozilla::ipc::MessageChannel::MessageTask &) z:\build\build\src\ipc\glue\MessageChannel.cpp:2019
    #62 0x7ff806517485 in mozilla::ipc::MessageChannel::MessageTask::Run(void) z:\build\build\src\ipc\glue\MessageChannel.cpp:2052
    #63 0x7ff80547809a in nsThread::ProcessNextEvent(bool,bool *) z:\build\build\src\xpcom\threads\nsThread.cpp:1246
    #64 0x7ff8054808e8 in NS_ProcessNextEvent(class nsIThread *,bool) z:\build\build\src\xpcom\threads\nsThreadUtils.cpp:530
    #65 0x7ff806520639 in mozilla::ipc::MessagePump::Run(class base::MessagePump::Delegate *) z:\build\build\src\ipc\glue\MessagePump.cpp:97
    #66 0x7ff80648649e in MessageLoop::RunHandler(void) z:\build\build\src\ipc\chromium\src\base\message_loop.cc:318
    #67 0x7ff806486226 in MessageLoop::Run(void) z:\build\build\src\ipc\chromium\src\base\message_loop.cc:298
    #68 0x7ff80f35765a in nsBaseAppShell::Run(void) z:\build\build\src\widget\nsBaseAppShell.cpp:158
    #69 0x7ff80f4e6717 in nsAppShell::Run(void) z:\build\build\src\widget\windows\nsAppShell.cpp:420
    #70 0x7ff81391946d in XRE_RunAppShell(void) z:\build\build\src\toolkit\xre\nsEmbedFunctions.cpp:939
    #71 0x7ff80648649e in MessageLoop::RunHandler(void) z:\build\build\src\ipc\chromium\src\base\message_loop.cc:318
    #72 0x7ff806486226 in MessageLoop::Run(void) z:\build\build\src\ipc\chromium\src\base\message_loop.cc:298
    #73 0x7ff8139186e0 in XRE_InitChildProcess(int,char * * const,struct XREChildData const *) z:\build\build\src\toolkit\xre\nsEmbedFunctions.cpp:765
    #74 0x7ff6a2d21f11  (C:\Program Files\Mozilla Developer Preview\firefox.exe+0x140001f11)
    #75 0x7ff6a2d214a1  (C:\Program Files\Mozilla Developer Preview\firefox.exe+0x1400014a1)
    #76 0x7ff6a2d2ebdb  (C:\Program Files\Mozilla Developer Preview\firefox.exe+0x14000ebdb)
    #77 0x7ff85b8e3033  (C:\Windows\System32\KERNEL32.DLL+0x180013033)
    #78 0x7ff85e041460  (C:\Windows\SYSTEM32\ntdll.dll+0x180071460)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: access-violation z:\build\build\src\layout\svg\SVGTextFrame.cpp:1518 in mozilla::TextNodeCorrespondenceRecorder::TraverseAndRecord(class nsIFrame *)
==8652==ABORTING
It would be nice to reduce this testcase and land a crash test, but that's not a quick task and so not the top priority for my time right now.
Assignee: nobody → jwatt
Priority: -- → P3
I've got it reduced down considerably, the testcase is only 20KB at this point.
Attachment #9022820 - Attachment is obsolete: true
OS: Windows 10 → All
Hardware: x86_64 → All
Attached file reduced test
Thanks Brian, here's that reduced test reduced even further.
Looking into this a bit, this is another case where displays:contents has confused the text node character counting code since it no longer matches what the frame tree is doing.

Normally a <textPath> will have its frame subtree suppressed if its parent (ignoring any ancestor <a>s) is not a <text>.  So in the comment 4 test, the inner <textPath> should not be displayed.  But ITEM_ALLOWS_TEXT_PATH_CHILD does get added in nsCSSFrameConstructor::DoAddFrameConstructionItems, because we are checking whether the parent frame is for a <text>, effectively skipping over the display:contents ancestors.

The TextNodeCorrespondenceRecorder uses TextFrameIterator to find all the nsTextFrames of interest, and it correctly skips over the incorrectly parented <textPath>.  But TextNodeCorrespondenceRecorder::TraverseAndRecord itself finds nsInlineFrame that got created for the <tspan> which should never have been displayed.

Emilio added some wallpapering in bug 1421807 to prevent display:contents on an element from creating text frames for any direct text node children, to avoid the character counting code, but that doesn't match this case here where the child of the display:contents is an element.


I think the patch here is OK, in that avoids this specific mismatch, but I think we should probably also fix the handling of display:contents on <textPath> issue here so that we either (a) decide that the nested <textPath> should not be displayed, since it is not allowed to have a <textPath> parent, or (b) decide that it's correct to display the <tspan>, since suppression of subtrees due to invalid elements within <text> should be done by ignoring display:contents.
Filed bug 1505249 to look at that.
Pushed by jwatt@jwatt.org:
https://hg.mozilla.org/integration/mozilla-inbound/rev/923646987d58
Prevent TextNodeCorrespondenceRecorder::TraverseAndRecord crash. r=heycam
https://hg.mozilla.org/mozilla-central/rev/923646987d58
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla65
Flags: in-testsuite+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: