Closed Bug 656244 Opened 14 years ago Closed 14 years ago

Crash when a malformed SVG is included in a page [@ mozilla::imagelib::SVGDocumentWrapper::GetWidthOrHeight ]

Categories

(Core :: SVG, defect)

defect
Not set
major

Tracking

()

VERIFIED FIXED
mozilla7
Tracking Status
firefox5 - ---
firefox6 - ---
firefox7 --- fixed
status1.9.2 --- unaffected

People

(Reporter: aki.helin, Assigned: dholbert)

References

()

Details

(Keywords: crash, testcase, Whiteboard: [sg:dos])

Crash Data

Attachments

(4 files)

User-Agent: Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Build Identifier: Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Firefox crashes when the attached HTML page is opened. The page includes one SVG file as an image. Reproducible: Sometimes Steps to Reproduce: 1. $ firefox test.html 2. reload the page a few times Actual Results: Firefox crashes. Expected Results: Firefox remains running. I tried a few variants of this and only got a null deref. Opening just the SVG file causes either a circle being drawn or an error. Firefox seems to crash only when the image is included on another page. Crash report @ https://crash-stats.mozilla.com/report/index/bp-ec7915a8-fe06-41bd-87d2-3cc042110511
0 libxul.so mozilla::imagelib::SVGDocumentWrapper::GetWidthOrHeight modules/libpr0n/src/SVGDocumentWrapper.cpp:113 1 libxul.so mozilla::imagelib::VectorImage::GetWidth modules/libpr0n/src/VectorImage.cpp:313 2 @0xacb2f09b 3 libxul.so nsImageFrame::UpdateIntrinsicSize layout/generic/nsImageFrame.cpp:309 4 libxul.so nsImageFrame::EnsureIntrinsicSizeAndRatio layout/generic/nsImageFrame.cpp:718 5 libxul.so nsImageFrame::ComputeSize layout/generic/nsImageFrame.cpp:746 6 libxul.so nsHTMLReflowState::InitConstraints layout/generic/nsHTMLReflowState.cpp:1849 7 libxul.so nsHTMLReflowState::Init layout/generic/nsHTMLReflowState.cpp:284 8 libxul.so nsLineLayout::ReflowFrame jstl.h:350 9 libxul.so nsBlockFrame::ReflowInlineFrame layout/generic/nsBlockFrame.cpp:3811 10 libxul.so nsBlockFrame::DoReflowInlineFrames layout/generic/nsBlockFrame.cpp:3607 11 libxul.so nsBlockFrame::ReflowInlineFrames layout/generic/nsBlockFrame.cpp:3466 12 libxul.so nsBlockFrame::ReflowLine layout/generic/nsBlockFrame.cpp:2562 13 libxul.so nsBlockFrame::ReflowDirtyLines layout/generic/nsBlockFrame.cpp:1999 14 libxul.so nsBlockFrame::Reflow layout/generic/nsBlockFrame.cpp:1080 15 libxul.so nsBlockReflowContext::ReflowBlock layout/generic/nsBlockReflowContext.cpp:297 16 libxul.so nsBlockFrame::ReflowBlockFrame layout/generic/nsBlockFrame.cpp:3184 17 libxul.so nsBlockFrame::ReflowLine layout/generic/nsBlockFrame.cpp:2506 18 libxul.so nsBlockFrame::ReflowDirtyLines layout/generic/nsBlockFrame.cpp:1999 19 libxul.so nsBlockFrame::Reflow layout/generic/nsBlockFrame.cpp:1080 20 libxul.so nsContainerFrame::ReflowChild layout/generic/nsContainerFrame.cpp:740 21 libxul.so nsCanvasFrame::Reflow layout/generic/nsCanvasFrame.cpp:494 22 libxul.so nsContainerFrame::ReflowChild layout/generic/nsContainerFrame.cpp:740 23 libxul.so nsHTMLScrollFrame::ReflowScrolledFrame layout/generic/nsGfxScrollFrame.cpp:535 24 libxul.so nsHTMLScrollFrame::ReflowContents layout/generic/nsGfxScrollFrame.cpp:627 25 libxul.so nsHTMLScrollFrame::Reflow layout/generic/nsGfxScrollFrame.cpp:868 26 libxul.so nsContainerFrame::ReflowChild layout/generic/nsContainerFrame.cpp:740 27 libxul.so ViewportFrame::Reflow layout/generic/nsViewportFrame.cpp:293 28 libxul.so PresShell::DoReflow layout/base/nsPresShell.cpp:7897 29 libxul.so PresShell::ProcessReflowCommands layout/base/nsPresShell.cpp:8036 30 libxul.so PresShell::FlushPendingNotifications layout/base/nsPresShell.cpp:4916 31 libxul.so nsRefreshDriver::Notify layout/base/nsRefreshDriver.cpp:326 32 libxul.so nsTimerImpl::Fire xpcom/threads/nsTimerImpl.cpp:428 33 libxul.so nsTimerEvent::Run xpcom/threads/nsTimerImpl.cpp:517 34 libxul.so nsThread::ProcessNextEvent xpcom/threads/nsThread.cpp:633 35 libxul.so NS_ProcessNextEvent_P nsThreadUtils.cpp:250 36 libxul.so mozilla::ipc::MessagePump::Run ipc/glue/MessagePump.cpp:110 37 libxul.so MessageLoop::RunInternal ipc/chromium/src/base/message_loop.cc:219 38 libxul.so MessageLoop::Run ipc/chromium/src/base/message_loop.cc:202 39 libxul.so nsBaseAppShell::Run widget/src/xpwidgets/nsBaseAppShell.cpp:192 40 libxul.so nsAppStartup::Run toolkit/components/startup/src/nsAppStartup.cpp:220 41 @0xb76877b3 42 libxul.so XRE_main toolkit/xre/nsAppRunner.cpp:3786 43 firefox-bin main nsBrowserApp.cpp:158 44 libc-2.11.2.so libc-2.11.2.so@0x16c75 45 firefox-bin firefox-bin@0x1390 46 firefox-bin Output nsBrowserApp.cpp:77 47 @0x1
Keywords: crash
Summary: crash at mozilla::imagelib::SVGDocumentWrapper::GetWidthOrHeight → Crash when a malformed SVG is included in a page [@ mozilla::imagelib::SVGDocumentWrapper::GetWidthOrHeight ]
Version: unspecified → 4.0 Branch
Works for me so far (no crash, but also no image viewed). Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110510 Firefox/6.0a1 Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 I've also tried to view just the SVG image in some programs, but they all issue an error message similar to: [13:54:07.797] mismatched tag. Expected: </animateColor>. @ file:///home/user1/Downloads/trigger.svg:3063 But of course, Firefox should not crash even with a malformed image file.
Component: General → Layout: Images
Product: Firefox → Core
QA Contact: general → layout.images
Version: 4.0 Branch → unspecified
How easy is it for you to reproduce the crash? Aki, are you able to reproduced the crash when running Firefox in Safe Mode? (The crash report shows that your profile doesn't have a lot of extensions, but anyway...) https://support.mozilla.com/en-US/kb/Safe+Mode How about with a new, empty profile? https://support.mozilla.com/en-US/kb/Basic+Troubleshooting#w_8-make-a-new-profile
The crash happens in safe mode and with a blank profile. This is mainly a fuzzing/testing machine so there shouldn't be any funny customizations. The crash rarely happens on first load, but it almost always happens on first or second reload.
Ah, this behaves like a race condition. The included test SVG file did not trigger this on another faster machine, but it is easily reproducible after adding 100 more of the repeating 11-line section. The other machine is similar to the one above (also Debian 6.0.1, i686, Firefox 4.0.1) but with Intel Core 2 Duo instead of an Atom.
Reproduced with a new clean profile, pressing F5 until crash. Build identifier: Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/4.0 bp-2594a28b-de9e-4d5f-b997-798602110511 This is on a laptop, weaker than the workstation I used in comment 4.
(In reply to comment #7) >..., but it is easily reproducible after adding 100 more of the repeating >11-line section. Do you mean that you have created a test file with 101 lines of "<img src="trigger.svg">"?
I meant editing just the SVG file and repeating the section: <script><![CDATA[SVGDoc=document;//]]></script> <defs id="DEF"> <linearGradient id="rhue" x1="0" x2="100" y1="100" y2="0" gradientUnits="userSpaceOnUse"> <stop offset="0" id="ro0" style="stop-color: red"/> <stop offset=".25" id="ro1" style="stop-color: blue"/> <stop offset=".75" id="ro2" style="stop-color: yellow"/> <stop offset="1" id="ro3" style="stop-color: green"/> </linearGradient></defs> <g transform="translate(0 50)"> <ellipse cx="290" cy="200" rx="80" ry="80"> <animateColor attri="http://www.w3.org/1999/xlink"> 100 more times. 1000 didn't work for me, but with 100 this reproduced several times with 1 or 2 reloads. Apparently when there is trouble ahead, instead of a broken image picture there is a partially shown parsing error message or a blank yellow box (background of the error message?) when there is no crash.
I eventually manged to crash Firefox on my powerful workstation as well, but I had to use stressapptest to make the computer a bit dizzy. :-) Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 bp-aeb84886-49cc-4e55-9199-15b3c2110511
(In reply to comment #10) > Apparently when there is trouble ahead, > instead of a broken image picture there is a partially shown parsing error > message or a blank yellow box (background of the error message?) when there > is no crash. Interesting, I also saw the yellow box flash shortly before the crash, by estimate the size of the error message I get when I look at the image directly. I could not see any text in it, but it was visible a very short moment so I may have missed it.
Alternative repro that might work better on desktop supercomputers: $ perl -e 'print "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n", "<defs> <linearGradient id=\"rhue\" x1=\"0\" x2=\"100\" y1=\"100\" y2=\"0\"> <stop style=\"stop-color: red\"/> </linearGradient></defs> <ellipse cx=\"290\" cy=\"200\" rx=\"80\" ry=\"80\"> <animateColor attri=\"http://www.w3.org/1999/xlink\">\n\n" x 800, "</lineargradient></svg>"' > foo.svg $ echo '<img src="foo.svg">' > test.html $ firefox test.html That one works on my slowish computer (crashes within a few reloads), and lifting the "x 800" might help on faster machines. Might be that just about any malformed SVG that takes the correct amount of time to parse would do it. The null crash, yellow box and partially shown error message would make sense for example if someone was trying to print the reason for the error while it was still being computed.
Reproduced with the original test.html and trigger.svg: Mozilla/5.0 (X11; Linux i686; rv:6.0a1) Gecko/20110511 Firefox/6.0a1 bp-72442292-5d83-4deb-9966-ca01d2110511 I pressed reload/stop as an idiot in a semi-random pattern - and suddenly when I pressed stop the XML Parsing Error box was on the screen. I downloaded and installed GIMP, made the attached screenshoot, and when I pressed reload again Firefox crashed.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Version: unspecified → Trunk
Hardware: x86 → All
I haven't yet reproduced the crash, but when I use a local copy of the testcase, I do seem to hit the "XML Parsing Error" yellow rendering every single time, and that that in and of itself is unexpected/bad -- we're supposed to catch that and display the broken-image icon instead. (I think both that and the crash have the same underlying problem.) The code to handle that is VectorImage::OnStopRequest() (called when we've received all the data for the image file) -- that checks mSVGDocumentWrapper->ParsedSuccessfully(), which checks the image-document's root element. If ParsedSuccessfully sees a non-<svg> root element in its document (e.g. the root node of the internal yellow XML error page), then it takes that as a sign that our SVG was malformed. But when I hit the yellow rendering here, we end up getting a <svg> element at that point, which makes us behave as if everything is fine (and paint the "image"). I'm not sure why that's happening...
Component: Layout: Images → SVG
QA Contact: layout.images → general
Keywords: testcase
Whiteboard: [sg:dos]
I believe bug 657191 fixed this -- in a current nightly, I can't hit the "XML Parsing Error" rendering that I previously could in comment 15. Can anyone else reproduce in an up-to-date Nightly (mozilla-central) build? Mozilla/5.0 (X11; Linux i686; rv:6.0a1) Gecko/20110524 Firefox/6.0a1
(In reply to comment #16) > I believe bug 657191 fixed this -- in a current nightly, I can't hit the > "XML Parsing Error" rendering that I previously could in comment 15 (that is to say -- I now always get a "broken image" icon instead, which is correct)
I get the same crash with current nightly (6.0a1 2011-05-24) and the original testcase. Heading off to an offline vacation so I can't test with other versions for a week. Crash report is at https://crash-stats.mozilla.com/report/index/bp-d385aa68-cadf-414d-bf9f-d4c962110525. Not sure why it shows 4.0.1 as version.
I still can't reproduce (now with a build from before bug 657191 landed), but I'm willing to believe that it's still broken. However... > I get the same crash with current nightly > Crash report is [...] Not sure why it shows 4.0.1 as version. I take this to mean you *actually* crashed on 4.0.1... (Maybe you already had Firefox 4.0.1 open & forgot to specify -no-remote when starting your nightly build?) Crash reports aren't generally wrong about the crashing version -- if they were, that'd be a very bad thing for our ability to track trends in crashes.
(In reply to comment #15) > If ParsedSuccessfully sees a non-<svg> root element in its > document (e.g. the root node of the internal yellow XML error page), then it > takes that as a sign that our SVG was malformed. > > But when I hit the yellow rendering here, we end up getting a <svg> element > at that point, which makes us behave as if everything is fine (and paint the > "image"). I'm not sure why that's happening... So when I load the attached (malformed) SVG file directly, I see a "normal" rendering (with a black circle) for a little bit, and *then* we switch to the XML Parsing error page. In theory we're supposed to be flushing all of the parsing (and hitting any parsing errors) before we check "ParsedSuccessfully". But it seems like in this case, given that we're seeing an <svg> root element, ParsedSuccessfully must still be seeing the pre-converted-to-error-page document somehow. I still don't know exactly why this is happening, but it makes sense that this would be related to the document size, as suggested in comment 10.
Ah, ok - so using a current debug build, I _can_ still reproduce the yellow-error-page-instead-of-broken-image rendering that I saw in comment 15. (probably because debug builds are slower). Still no crashes, though. So, definitely not fixed by bug 657191.
d'oh, we're definitely getting a call to nsParser::ContinueInterruptedParsing() *after* the ParsedSuccessfully check. (And there's a call to nsExpatDriver::HandleError inside of that ContinueInterruptedParsing call, which is what switches to the error page.) I think I initially assumed that SVGDocumentWrapper's call to ContinueInterruptedParsing would finish off all remaining parsing, but I guess it only does one more "batch"... We may need to wrap it in some sort of "while(moreParsingToDo) {}" loop. Marking this as security-sensitive, since this could can definitely have crashy implications, some of which could be scary (not sure yet).
Group: core-security
(In reply to comment #15) > I haven't yet reproduced the crash, but when I use a local copy of the > testcase, I do seem to hit the "XML Parsing Error" yellow rendering BTW, it makes sense that this would particularly affect local-file-loads, because it happens when we're loading data fast enough that the parser "falls behind" and is left needing multiple ContinueInterruptedParsing batches even after we've received all the data from the file request.
So bug 599497 comment 6 added: >+ if (!parser->IsComplete()) { >+ parser->ContinueInterruptedParsing(); I think we just want "while" instead of "if" there.
Depends on: 599497
Attached patch fix v1Splinter Review
Assignee: nobody → dholbert
Status: NEW → ASSIGNED
Attachment #535506 - Flags: review?(jst)
This code hasn't changed since Firefox 4, so this bug affects us back that far. I think we need this on all active release trains (for Firefox 5 and 6).
OS: Linux → All
Not tracking a dos for 5.
Comment on attachment 535506 [details] [diff] [review] fix v1 Switching review request to Henri. I'm not sure continuing interrupted parsing in a synchronous loop is something that the parser expects and will always be ok with. But I'm guessing Henri will know.
Attachment #535506 - Flags: review?(jst) → review?(hsivonen)
Comment on attachment 535506 [details] [diff] [review] fix v1 ContinueInterruptedParsing() is meant to be called from the event loop, so neither the code before the patch nor the code after the patch is OK. Instead of calling into the parser like this, I think the right way to proceed would be to let the parser finish at its own pace asynchronously and then to hook whatever code the SVG-in-img code needs to run last to code that runs around nsXMLContentSink::DidBuildModel(). I see the comment right above your code change though. If the assumptions of imgRequest::OnStopRequest are too hard to change, you might just get away with calling ContinueInterruptedParsing() in a loop assuming that SVG-in-img is guaranteed never to run scripts. However, I'm not sure that you can get away with in that case. Are the assumptions of imgRequest::OnStopRequest too hard to change?
(In reply to comment #29) > I see the comment right above your code change though. Just for clarity, that comment is: >298 // A few levels up the stack, imgRequest::OnStopRequest is about to tell >299 // all of its observers that we know our size and are ready to paint. That >300 // might not be true at this point, though -- so here, we synchronously >301 // finish parsing & layout in our helper-document to make sure we can hold >302 // up to this promise. > If the assumptions of > imgRequest::OnStopRequest are too hard to change, you might just get away > with calling ContinueInterruptedParsing() in a loop assuming that SVG-in-img > is guaranteed never to run scripts. That's my thinking as well. And we do indeed have that guarantee. > Are the assumptions of imgRequest::OnStopRequest too > hard to change? IIRC from discussion with Joe and/or Bobby, that would require some nontrivial refactoring of imagelib code, to separate out the "received all the data" and "have image size available" conditions. I think I remember bholley saying that this refactoring is wanted eventually, but it's non-trivial. Henri: would you agree that the addition of the loop here is at least an improvement over what we have now? :)
Crash Signature: [@ mozilla::imagelib::SVGDocumentWrapper::GetWidthOrHeight ]
Not version-specific so not tracking for Firefox 6.
Comment on attachment 535506 [details] [diff] [review] fix v1 comment 29 looks like an r-, setting flag so no one is misled by the bug state
Attachment #535506 - Flags: review?(hsivonen) → review-
If it's a DoS bug should we unhide it?
Comment on attachment 535506 [details] [diff] [review] fix v1 (In reply to comment #30) > Henri: would you agree that the addition of the loop here is at least an > improvement over what we have now? :) Yes. It's an improvement. Sorry about the delay, I thought I had already responded. Marking r+ in the "it's an improvement" sense. I can't promise that the solution still wouldn't be broken in some way that I just fail to see right now.
Attachment #535506 - Flags: review- → review+
Whiteboard: [sg:dos] → [sg:dos][inbound]
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Whiteboard: [sg:dos][inbound] → [sg:dos]
Target Milestone: --- → mozilla7
Group: core-security
I was able to view the image for about one-two seconds in the tab and after that the error appeared: "XML Parsing Error: mismatched tag. Expected: </animateColor>. Location: https://bug656244.bugzilla.mozilla.org/attachment.cgi?id=531579 Line Number 3063, Column 3:" I've tried this on Mozilla/5.0 (Windows NT 6.1; rv:7.0) Gecko/20100101 Firefox/7.0 beta 1. So the issue is still reproducing for me. I don't get a Firefox crash but that error page.
(In reply to Vlad from comment #39) > I was able to view the image for about one-two seconds in the tab and after > that the error appeared: "XML Parsing Error: mismatched tag. Expected: > </animateColor>. > Location: https://bug656244.bugzilla.mozilla.org/attachment.cgi?id=531579 > Line Number 3063, Column 3:" That's the expected result. The previous behaviour was a crash which was fixed.
Attachment #531580 - Attachment mime type: text/plain → text/html
Attachment #531580 - Attachment description: testcase → testcase (needs to be downloaded locally, along w/ SVG file, to work)
Considering comment39 and comment40, setting resolution to Verified Fixed on Mozilla/5.0 (Windows NT 6.1; rv:7.0) Gecko/20100101 Firefox/7.0
Status: RESOLVED → VERIFIED
Depends on: 694165
(In reply to Daniel Holbert [:dholbert] from comment #30) > > Are the assumptions of imgRequest::OnStopRequest too > > hard to change? > > IIRC from discussion with Joe and/or Bobby, that would require some > nontrivial refactoring of imagelib code, to separate out the "received all > the data" and "have image size available" conditions. I just filed bug 704059 on doing this refactoring, BTW, to be sure it's being tracked somewhere. (Not sure if there was already a bug filed on that; if so, mine can be duped to the original.)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: