Closed Bug 807891 Opened 13 years ago Closed 11 years ago

Out-of-bounds read in PropertyProvider::GetSpacingInternal

Categories

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

x86_64
All
defect
Not set
critical

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: inferno, Unassigned)

Details

(4 keywords, Whiteboard: [asan])

Attachments

(3 files)

Attached file Testcase
Reproduces on trunk. ================================================================= ==19627== ERROR: AddressSanitizer heap-buffer-overflow on address 0x7f1d6486bda5 at pc 0x7f1d70b62e15 bp 0x7fffe58dde30 sp 0x7fffe58dde28 READ of size 1 at 0x7f1d6486bda5 thread T0 #0 0x7f1d70b62e14 in nsTextFragment::CharAt(int) const layout/base/../../content/base/src/nsTextFragment.h:178 #1 0x7f1d7171d1d5 in IsCSSWordSpacingSpace(nsTextFragment const*, unsigned int, nsStyleText const*) layout/generic/nsTextFrameThebes.cpp:661 #2 0x7f1d7171af52 in PropertyProvider::GetSpacingInternal(unsigned int, unsigned int, gfxFont::Spacing*, bool) layout/generic/nsTextFrameThebes.cpp:2915 #3 0x7f1d7171e875 in PropertyProvider::CalcTabWidths(unsigned int, unsigned int) layout/generic/nsTextFrameThebes.cpp:3044 #4 0x7f1d7171b587 in PropertyProvider::GetSpacingInternal(unsigned int, unsigned int, gfxFont::Spacing*, bool) layout/generic/nsTextFrameThebes.cpp:2934 #5 0x7f1d71719e12 in PropertyProvider::GetSpacing(unsigned int, unsigned int, gfxFont::Spacing*) layout/generic/nsTextFrameThebes.cpp:2873 #6 0x7f1d7d481e5e in GetAdjustedSpacing(gfxTextRun*, unsigned int, unsigned int, gfxTextRun::PropertyProvider*, gfxFont::Spacing*) gfx/thebes/gfxFont.cpp:4679 #7 0x7f1d7d480d34 in gfxTextRun::GetAdjustedSpacingArray(unsigned int, unsigned int, gfxTextRun::PropertyProvider*, unsigned int, unsigned int, nsTArray<gfxFont::Spacing, nsTArrayDefaultAllocator>*) gfx/thebes/gfxFont.cpp:4710 #8 0x7f1d7d48b619 in gfxTextRun::AccumulateMetricsForRun(gfxFont*, unsigned int, unsigned int, gfxFont::BoundingBoxType, gfxContext*, gfxTextRun::PropertyProvider*, unsigned int, unsigned int, gfxFont::RunMetrics*) gfx/thebes/gfxFont.cpp:4978 #9 0x7f1d7d489217 in gfxTextRun::MeasureText(unsigned int, unsigned int, gfxFont::BoundingBoxType, gfxContext*, gfxTextRun::PropertyProvider*) gfx/thebes/gfxFont.cpp:5049 #10 0x7f1d717a88e9 in nsTextFrame::RecomputeOverflow(nsHTMLReflowState const&) layout/generic/nsTextFrameThebes.cpp:8233 #11 0x7f1d715c2989 in nsLineLayout::RelativePositionFrames(nsLineLayout::PerSpanData*, nsOverflowAreas&) layout/generic/nsLineLayout.cpp:2680 #12 0x7f1d715c1227 in nsLineLayout::RelativePositionFrames(nsOverflowAreas&) layout/generic/nsLineLayout.cpp:2599 #13 0x7f1d71257f72 in nsBlockFrame::PlaceLine(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFloatManager::SavedState*, nsRect&, int&, bool*) layout/generic/nsBlockFrame.cpp:4158 #14 0x7f1d7124fec9 in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) layout/generic/nsBlockFrame.cpp:3638 #15 0x7f1d71240349 in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:3356 #16 0x7f1d7122fb43 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:2474 #17 0x7f1d71216c17 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) layout/generic/nsBlockFrame.cpp:1991 #18 0x7f1d71209eb3 in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsBlockFrame.cpp:1043 #19 0x7f1d712f51ec in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:941 #20 0x7f1d712d68e3 in nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&, nsColumnSetFrame::ReflowConfig const&, bool, nsCollapsingMargin*, nsColumnSetFrame::ColumnBalanceData&) layout/generic/nsColumnSetFrame.cpp:660 #21 0x7f1d712dcd0b in nsColumnSetFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsColumnSetFrame.cpp:939 #22 0x7f1d71297650 in nsBlockReflowContext::ReflowBlock(nsRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) layout/generic/nsBlockReflowContext.cpp:268 #23 0x7f1d7123aa81 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:3088 #24 0x7f1d7122f862 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) layout/generic/nsBlockFrame.cpp:2471 #25 0x7f1d71216c17 in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) layout/generic/nsBlockFrame.cpp:1991 #26 0x7f1d71209eb3 in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsBlockFrame.cpp:1043 #27 0x7f1d712f51ec in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:941 #28 0x7f1d714c83e9 in nsCanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsCanvasFrame.cpp:465 #29 0x7f1d712f51ec in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:941 #30 0x7f1d7143e058 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) layout/generic/nsGfxScrollFrame.cpp:433 #31 0x7f1d71442bf6 in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) layout/generic/nsGfxScrollFrame.cpp:533 #32 0x7f1d71447280 in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsGfxScrollFrame.cpp:774 #33 0x7f1d712f51ec in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned int, unsigned int&, nsOverflowContinuationTracker*) layout/generic/nsContainerFrame.cpp:941 #34 0x7f1d718361aa in ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) layout/generic/nsViewportFrame.cpp:209 #35 0x7f1d70f6f0bb in PresShell::DoReflow(nsIFrame*, bool) layout/base/nsPresShell.cpp:7461 #36 0x7f1d70f9df67 in PresShell::ProcessReflowCommands(bool) layout/base/nsPresShell.cpp:7602 #37 0x7f1d70f9ca6e in PresShell::FlushPendingNotifications(mozFlushType) layout/base/nsPresShell.cpp:3906 #38 0x7f1d714838d1 in nsGfxScrollFrameInner::AsyncScrollPortEvent::Run() layout/generic/nsGfxScrollFrame.cpp:2903 #39 0x7f1d70f257a7 in nsRootPresContext::FlushWillPaintObservers() layout/base/nsPresContext.cpp:2816 #40 0x7f1d70ff60d7 in PresShell::WillPaint(bool) layout/base/nsPresShell.cpp:7040 #41 0x7f1d74d64aa7 in nsViewManager::CallWillPaintOnObservers(bool) view/src/nsViewManager.cpp:1250 #42 0x7f1d74d71a07 in nsViewManager::ProcessPendingUpdates() view/src/nsViewManager.cpp:1210 #43 0x7f1d710426e8 in nsRefreshDriver::Notify(nsITimer*) layout/base/nsRefreshDriver.cpp:432 #44 0x7f1d7ce4290d in nsTimerImpl::Fire() xpcom/threads/nsTimerImpl.cpp:485 #45 0x7f1d7ce43d2a in nsTimerEvent::Run() xpcom/threads/nsTimerImpl.cpp:565 #46 0x7f1d7ce0617f in nsThread::ProcessNextEvent(bool, bool*) xpcom/threads/nsThread.cpp:627 #47 0x7f1d7ca85cab in NS_ProcessNextEvent_P(nsIThread*, bool) objdir-ff-asan-sym/xpcom/build/nsThreadUtils.cpp:221 #48 0x7f1d7b32fad6 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) ipc/glue/MessagePump.cpp:82 #49 0x7f1d7d0ef281 in MessageLoop::RunInternal() ipc/chromium/src/base/message_loop.cc:215 #50 0x7f1d7d0ef0b6 in MessageLoop::RunHandler() ipc/chromium/src/base/message_loop.cc:208 #51 0x7f1d7d0eef9b in MessageLoop::Run() ipc/chromium/src/base/message_loop.cc:182 #52 0x7f1d7a74024a in nsBaseAppShell::Run() widget/xpwidgets/nsBaseAppShell.cpp:163 #53 0x7f1d792d1e94 in nsAppStartup::Run() toolkit/components/startup/nsAppStartup.cpp:290 #54 0x7f1d6ed57251 in XREMain::XRE_mainRun() toolkit/xre/nsAppRunner.cpp:3800 #55 0x7f1d6ed5d13b in XREMain::XRE_main(int, char**, nsXREAppData const*) toolkit/xre/nsAppRunner.cpp:3867 #56 0x7f1d6ed60034 in XRE_main toolkit/xre/nsAppRunner.cpp:3942 #57 0x40c135 in do_main(int, char**) browser/app/nsBrowserApp.cpp:174 #58 0x409837 in main browser/app/nsBrowserApp.cpp:279 #59 0x7f1d8e2a076c in ?? ??:0 0x7f1d6486bda5 is located 27 bytes to the left of 29-byte region [0x7f1d6486bdc0,0x7f1d6486bddd) allocated by thread T0 here: #0 0x4c3ef0 in malloc ??:? #1 0x7f1d8c01d55a in moz_xmalloc memory/mozalloc/mozalloc.cpp:54 #2 0x7f1d7ce884b6 in NS_Alloc_P xpcom/base/nsMemoryImpl.cpp:162 #3 0x7f1d6eeba026 in nsMemory::Alloc(unsigned long) ../../../dist/include/nsMemory.h:36 #4 0x7f1d72ce7fc1 in nsTextFragment::SetTo(unsigned short const*, int, bool) content/base/src/nsTextFragment.cpp:257 #5 0x7f1d72a792ae in nsGenericDOMDataNode::SetTextInternal(unsigned int, unsigned int, unsigned short const*, unsigned int, bool, CharacterDataChangeInfo::Details*) content/base/src/nsGenericDOMDataNode.cpp:284 #6 0x7f1d72a869d8 in nsGenericDOMDataNode::SetText(unsigned short const*, unsigned int, bool) content/base/src/nsGenericDOMDataNode.cpp:827 #7 0x7f1d7622ca78 in nsHtml5TreeOperation::AppendText(unsigned short const*, unsigned int, nsIContent*, nsHtml5TreeOpExecutor*) parser/html/nsHtml5TreeOperation.cpp:166 #8 0x7f1d76237ba6 in nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor*, nsIContent**) parser/html/nsHtml5TreeOperation.cpp:457 Shadow byte and word: 0x1fe3ac90d7b4: fa 0x1fe3ac90d7b0: fa fa fa fa fa fa fa fa More shadow bytes: 0x1fe3ac90d790: fa fa fa fa fa fa fa fa 0x1fe3ac90d798: fd fd fd fd fd fd fd fd 0x1fe3ac90d7a0: fa fa fa fa fa fa fa fa 0x1fe3ac90d7a8: fd fd fd fd fd fd fd fd =>0x1fe3ac90d7b0: fa fa fa fa fa fa fa fa 0x1fe3ac90d7b8: 00 00 00 05 fb fb fb fb 0x1fe3ac90d7c0: fa fa fa fa fa fa fa fa 0x1fe3ac90d7c8: fd fd fd fd fd fd fd fd 0x1fe3ac90d7d0: fa fa fa fa fa fa fa fa Stats: 242M malloced (229M for red zones) by 400005 calls Stats: 45M realloced by 24426 calls Stats: 210M freed by 266279 calls Stats: 172M really freed by 230961 calls Stats: 230M (59080 full pages) mmaped in 437 calls mmaps by size class: 7:147420; 8:45034; 9:13299; 10:5110; 11:7140; 12:1408; 13:832; 14:576; 15:144; 16:712; 17:452; 18:36; 19:35; 20:22; mallocs by size class: 7:260120; 8:83422; 9:22995; 10:8438; 11:15968; 12:2510; 13:1828; 14:1558; 15:312; 16:1403; 17:1325; 18:64; 19:39; 20:23; frees by size class: 7:171606; 8:53025; 9:16576; 10:5291; 11:12714; 12:1511; 13:1338; 14:1382; 15:254; 16:1166; 17:1308; 18:51; 19:37; 20:20; rfrees by size class: 7:153452; 8:45144; 9:10799; 10:3840; 11:11632; 12:1218; 13:1007; 14:1301; 15:217; 16:1015; 17:1279; 18:50; 19:6; 20:1; Stats: malloc large: 3166 small slow: 4879 ==19627== ABORTING
Severity: normal → critical
Component: General → Layout: Text
Keywords: crash, testcase
Product: Firefox → Core
Whiteboard: [asan]
When I run this in a debug build, I get this assertion, which is in a file that at least appears near the top of the stack: ###!!! ASSERTION: Precomputed tab widths are missing!: 'mTabWidths && mTabWidths->mLimit >= i', file /Users/amccreight/mz/cent/layout/generic/nsTextFrameThebes.cpp, line 3024
For the moment it appears we're over-reading the string to compute layout and shouldn't be writing back out to it. If it looks like we do, however, this would be a more severe problem.
Summary: Heap-buffer-overflow in PropertyProvider::GetSpacingInternal → Out-of-bounds read in PropertyProvider::GetSpacingInternal
Attached file Testcase #2
The original test use "white-space: -moz-pre-discard-newlines" which was dropped in bug 1019555. This test is the same as the original except it uses "white-space: -moz-pre-space" instead. Although, I guess the new value isn't semantically the same as the old one. Both tests works for me in a local m-c ASAN debug Linux64 build. No crash and no assertions.
Perhaps the underlying bug was in our implementation of -moz-pre-discard-newlines and that by removing that code (bug 1019555) we fixed it?
Flags: needinfo?(cam)
Sounds like it could be related to that bug. I don't have time to look into this at the moment -- is it something you can investigate Mats?
Flags: needinfo?(cam) → needinfo?(mats)
Not anytime soon, sorry. I guess what we should do here is go back to a revision before bug 1019555 landed and debug the original testcase to figure out what the crash really was about.
Flags: needinfo?(mats)
CCing some SVG folks in case they have time to investigate.
Attached patch 1019555-rollbackSplinter Review
I reverted bug 1019555 locally but it still doesn't crash so I guess it was something else that fixed it.
Status: NEW → RESOLVED
Closed: 11 years ago
Flags: in-testsuite?
Resolution: --- → WORKSFORME
Group: core-security → core-security-release
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: