Closed Bug 320459 Opened 19 years ago Closed 18 years ago

Crash in Firefox 1.5 involving <legend>, <kbd>, and <object> [@ nsBlockFrame::IsFloatContainingBlock] [@ IsContinuationPlaceholder]

Categories

(Core :: Layout: Block and Inline, defect)

1.8 Branch
defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla1.8.1

People

(Reporter: bugtraq, Assigned: bzbarsky)

References

()

Details

(5 keywords, Whiteboard: [sg:dos][rft-dl])

Crash Data

Attachments

(4 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8) Gecko/20051111 Firefox/1.5
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8) Gecko/20051111 Firefox/1.5

Following HTML source forces Firefox 1.5 to crash:
> <legend>
>  <kbd>
>    <object>
>      <h4>
>    </object>
>  </kbd>

eax=00000003 ebx=0012dff8 ecx=00000000 edx=00000000 esi=00000000 edi=00000002
eip=00000000 esp=0289028a ebp=02890282 iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000297

No prior disassembly possible

Reproducible: Always

Steps to Reproduce:
Visit online demo:
http://morph3us.org/security/pen-testing/firefox/firefox15-1132914891046.nosymbols.00000000.html
Actual Results:  
Access Violation

Expected Results:  
-

-
Thread 0 Crashed:

nsBlockFrame::IsFloatContainingBlock() const + 32
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, int*, unsigned char*, int, int) + 444
nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, int*, int, int) + 148
nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, int*, int) + 972
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&, int) + 776
nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 1016
nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned, unsigned&) + 148
nsFieldSetFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 852
nsBlockReflowContext::ReflowBlock(nsRect const&, int, nsCollapsingMargin&, int, int, nsMargin&, nsHTMLReflowState&, unsigned&) + 1180
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, int*) + 1232
nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, int*, int) + 160
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&, int) + 776
nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 1016
nsBlockReflowContext::ReflowBlock(nsRect const&, int, nsCollapsingMargin&, int, int, nsMargin&, nsHTMLReflowState&, unsigned&) + 1180
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, int*) + 1232
nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, int*, int) + 160
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&, int) + 776
nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 1016
nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned, unsigned&) + 148
CanvasFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 356
nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned, unsigned&) + 148
nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState const&, int, int, nsHTMLReflowMetrics*, int) + 400
nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) + 232
nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 736
nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, int, int, unsigned, unsigned&) + 148
ViewportFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned&) + 300
IncrementalReflow::Dispatch(nsPresContext*, nsHTMLReflowMetrics&, nsSize const&, nsIRenderingContext&) + 280
PresShell::ProcessReflowCommands(int) + 512
FbMergeRopBits + 81200
PL_HandleEvent + 36
PL_ProcessPendingEvents + 128
__CFRunLoopDoSources0 + 384
__CFRunLoopRun + 452
CFRunLoopRunSpecific + 268
RunCurrentEventLoopInMode + 264
GetNextEventMatchingMask + 400
WNEInternal + 140
WaitNextEvent + 76
nsMacMessagePump::GetEvent(EventRecord&) + 116
nsMacMessagePump::DoMessagePump() + 48
nsAppShell::Run() + 56
nsAppStartup::Run() + 60
XRE_main + 3792
start + 432
start + 48
That's with Firefox 1.5 (release, not debug) on Mac OS X.
Blocks: Zalewski
Summary: DoS Vulnerability in Firefox 1.5 → Crash in Firefox 1.5 involving <legend>, <kbd>, and <object> [@ nsBlockFrame::IsFloatContainingBlock]
I don't crash with a debug Firefox 1.5 build on winxp without the leading > but do get this assert:

###!!! ASSERTION: prev sibling not in line list: 'Not Reached', file c:/work/mozilla/builds/ff/1.5/mozilla/layout/generic/nsBlockFrame.cpp, line 5318

I do crash on the url with stack:

+	aFrame	0x00000000
-	nsLayoutAtoms::placeholderFrame	0x03118810
+	[nsStaticAtomWrapper]	{...}
+	nsISupports	{...}


IsContinuationPlaceholder(nsIFrame * 0x00000000) line 552 + 3 bytes
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState & {...}, nsLineLayout & {...}, nsLineList_iterator {...}, int * 0x0012cf10, unsigned char * 0x0012cc5b, int 0x00000000, int 0x00000001) line 3857 + 9 bytes
nsBlockFrame::ReflowInlineFrames(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012cf10, int 0x00000001, int 0x00000000) line 3734 + 46 bytes
nsBlockFrame::ReflowLine(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012cf10, int 0x00000001) line 2728 + 33 bytes
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState & {...}, int 0x00000001) line 2262 + 31 bytes
nsBlockFrame::Reflow(nsBlockFrame * const 0x0417b2a0, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 902 + 17 bytes
nsLegendFrame::Reflow(nsLegendFrame * const 0x0417b2a0, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 123 + 25 bytes
nsContainerFrame::ReflowChild(nsIFrame * 0x0417b2a0, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, int 0x00000000, int 0x00000000, unsigned int 0x00000003, unsigned int & 0x00000000) line 904 + 31 bytes
nsFieldSetFrame::Reflow(nsFieldSetFrame * const 0x0417b01c, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 428
nsBlockReflowContext::ReflowBlock(const nsRect & {...}, int 0x00000000, nsCollapsingMargin & {...}, int 0x00000000, int 0x00000001, nsMargin & {...}, nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 605 + 42 bytes
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012df2c) line 3449 + 66 bytes
nsBlockFrame::ReflowLine(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012df2c, int 0x00000001) line 2610 + 27 bytes
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState & {...}, int 0x00000001) line 2262 + 31 bytes
nsBlockFrame::Reflow(nsBlockFrame * const 0x0417aa44, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 902 + 17 bytes
nsBlockReflowContext::ReflowBlock(const nsRect & {...}, int 0x00000001, nsCollapsingMargin & {...}, int 0x00000000, int 0x00000001, nsMargin & {...}, nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 605 + 42 bytes
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012eb78) line 3449 + 66 bytes
nsBlockFrame::ReflowLine(nsBlockReflowState & {...}, nsLineList_iterator {...}, int * 0x0012eb78, int 0x00000001) line 2610 + 27 bytes
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState & {...}, int 0x00000001) line 2262 + 31 bytes
nsBlockFrame::Reflow(nsBlockFrame * const 0x04178b58, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 902 + 17 bytes
nsContainerFrame::ReflowChild(nsIFrame * 0x04178b58, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, int 0x00000000, int 0x00000000, unsigned int 0x00000000, unsigned int & 0x00000000) line 904 + 31 bytes
CanvasFrame::Reflow(CanvasFrame * const 0x041720d0, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 536
nsContainerFrame::ReflowChild(nsIFrame * 0x041720d0, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, int 0x00000000, int 0x00000000, unsigned int 0x00000003, unsigned int & 0x00000000) line 904 + 31 bytes
nsHTMLScrollFrame::ReflowScrolledFrame(const ScrollReflowState & {...}, int 0x00000000, int 0x00000000, nsHTMLReflowMetrics * 0x0012f454, int 0x00000001) line 515 + 54 bytes
nsHTMLScrollFrame::ReflowContents(ScrollReflowState * 0x0012f5fc, const nsHTMLReflowMetrics & {...}) line 570 + 27 bytes
nsHTMLScrollFrame::Reflow(nsHTMLScrollFrame * const 0x0417221c, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 768 + 16 bytes
nsContainerFrame::ReflowChild(nsIFrame * 0x0417221c, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, int 0x00000000, int 0x00000000, unsigned int 0x00000000, unsigned int & 0x00000000) line 904 + 31 bytes
ViewportFrame::Reflow(ViewportFrame * const 0x0417203c, nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsHTMLReflowState & {...}, unsigned int & 0x00000000) line 239 + 43 bytes
IncrementalReflow::Dispatch(nsPresContext * 0x040dd8b8, nsHTMLReflowMetrics & {...}, const nsSize & {...}, nsIRenderingContext & {...}) line 912
PresShell::ProcessReflowCommands(int 0x00000001) line 6870
ReflowEvent::HandleEvent() line 6696
HandlePLEvent(ReflowEvent * 0x040450a8) line 6713
PL_HandleEvent(PLEvent * 0x040450a8) line 688 + 10 bytes
PL_ProcessPendingEvents(PLEventQueue * 0x00f250c8) line 623 + 9 bytes
_md_EventReceiverProc(HWND__ * 0x001b03c8, unsigned int 0x0000c14a, unsigned int 0x00000000, long 0x00f250c8) line 1408 + 9 bytes
USER32! 77d48734()
USER32! 77d48816()
USER32! 77d489cd()
USER32! 77d48a10()
nsAppShell::Run(nsAppShell * const 0x01379f70) line 135
nsAppStartup::Run(nsAppStartup * const 0x01379ed0) line 150 + 26 bytes
XRE_main(int 0x00000003, char * * 0x003f6fb8, const nsXREAppData * 0x0042201c kAppData) line 2313 + 35 bytes
main(int 0x00000003, char * * 0x003f6fb8) line 61 + 18 bytes
mainCRTStartup() line 338 + 17 bytes
KERNEL32! 7c816d4f()


Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Crash in Firefox 1.5 involving <legend>, <kbd>, and <object> [@ nsBlockFrame::IsFloatContainingBlock] → Crash in Firefox 1.5 involving <legend>, <kbd>, and <object> [@ nsBlockFrame::IsFloatContainingBlock] [@ IsContinuationPlaceholder]
I get a similar stack on windows except the null deref is when nsBlockFrame::DoReflowInlineFrames calls IsContinuationPlaceholder() instead. And a little ways up there's a nsLegendFrame::Reflow between the  nsContainerFrame::ReflowChild and nsBlockFrame::Reflow
Severity: normal → critical
Component: Security → Layout: Block and Inline
Keywords: crash
Product: Firefox → Core
QA Contact: firefox → layout.block-and-inline
Whiteboard: [sg:dos]
Version: unspecified → Trunk
I see the crash on the branch but not the trunk.  It was fixed on the trunk between 2005-09-18-06-trunk and 2005-09-19-06-trunk Linux Firefox nightlies.
(Probably that was bug 11011, but that's not something we want on the branch.)
Version: Trunk → 1.8 Branch
Attached patch 1.8 branch fixSplinter Review
Just when we thought SplitToContainingBlock was dead... :(

The problem is that the <legend> is display:inline so SplitToContainingBlock tries to split it (since the <h4> is a block).  That gets the fieldset's knickers all twisted, asserts fire, and we crash.

The solution is to fix SplitToContainingBlock to only split inlines instead of splitting anything that's not a block.  This is similar to a change we made to WipeContainingBlock at some point on trunk.

Note that on trunk this method is gone (removed in bug 11011, as dbaron guessed), so no issue there.

Do we need this on the 1.7 branch?  I _think_ it might Just Work there, but I'd need to make sure it compiles or something.
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Attachment #208057 - Flags: superreview?(dbaron)
Attachment #208057 - Flags: review?(dbaron)
Keywords: testcase
Flags: blocking1.8.1?
Flags: blocking1.8.0.2?
Flags: blocking1.7.13?
Attachment #208057 - Flags: superreview?(dbaron)
Attachment #208057 - Flags: superreview+
Attachment #208057 - Flags: review?(dbaron)
Attachment #208057 - Flags: review+
Comment on attachment 208057 [details] [diff] [review]
1.8 branch fix

Requesting branch approvals for the various branches...  This is a reasonably low-risk fix for a security-issue crasher.
Attachment #208057 - Flags: approval1.8.1?
Attachment #208057 - Flags: approval1.8.0.2?
Attachment #208057 - Flags: approval1.7.13?
Attachment #208057 - Flags: approval-aviary1.0.8?
Flags: blocking-aviary1.0.8?
(In reply to comment #9)
> low-risk fix for a security-issue crasher.

Is this more than just a DoS then?
Attachment #208057 - Flags: approval1.8.1? → branch-1.8.1?(dbaron)
It's been a while since I debugged this, but I seem to recall crashing due to the usual frame thing -- virtual function calls on dead stuff.
Flags: blocking1.8.1?
Flags: blocking1.8.1+
Flags: blocking1.8.0.2?
Flags: blocking1.8.0.2+
Flags: blocking1.7.13?
Flags: blocking1.7.13+
Flags: blocking-aviary1.0.8?
Flags: blocking-aviary1.0.8+
Comment on attachment 208057 [details] [diff] [review]
1.8 branch fix

a=dveditz for drivers, please add fixed-aviary1.0.8, fixed1.7.13, and fixed1.8.0.2 keywords when checked in to the branches
Attachment #208057 - Flags: branch-1.8.1?(dbaron)
Attachment #208057 - Flags: branch-1.8.1+
Attachment #208057 - Flags: approval1.8.0.2?
Attachment #208057 - Flags: approval1.8.0.2+
Attachment #208057 - Flags: approval1.7.13?
Attachment #208057 - Flags: approval1.7.13+
Attachment #208057 - Flags: approval-aviary1.0.8?
Attachment #208057 - Flags: approval-aviary1.0.8+
*** Committing to MOZILLA_1_8_BRANCH... 
new revision: 1.1110.6.15; previous revision: 1.1110.6.14

*** Committing layout/base/nsCSSFrameConstructor.cpp on MOZILLA_1_8_0_BRANCH... 
new revision: 1.1110.6.12.2.3; previous revision: 1.1110.6.12.2.2
Fixed on 1.7 and aviary branch too.
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.8.1
Verified for 1.0.8 release using Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.12) Gecko/20060208 Firefox/1.0.7 (build has not yet been renamed). I  did not crash visiting the online demo that the reporter pasted in the bug. Adding  verified-aviary1.0.8 keyword.
Flags: testcase+
Whiteboard: [sg:dos] → [sg:dos][rft-dl]
Group: security
Verified FIXED using Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8) Gecko/20060203 Firefox/1.5 and the testcase from attachment 206027 [details].
Status: RESOLVED → VERIFIED
Flags: in-testsuite+ → in-testsuite?
crash test landed
http://hg.mozilla.org/mozilla-central/rev/782d80d2a4c8
Flags: in-testsuite? → in-testsuite+
Crash Signature: [@ nsBlockFrame::IsFloatContainingBlock] [@ IsContinuationPlaceholder]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: