A tiny, malicious SVG file causes firefox to stall and use up the system's memory

NEW
Unassigned

Status

()

--
critical
11 years ago
3 years ago

People

(Reporter: ebosman, Unassigned)

Tracking

({perf, testcase})

unspecified
perf, testcase
Points:
---
Bug Flags:
wanted1.9.2 +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [use] [external-report], URL)

Attachments

(6 attachments)

(Reporter)

Description

11 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9) Gecko/2008061017 Firefox/3.0
Build Identifier: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9) Gecko/2008061017 Firefox/3.0

Using SVG and xlink, it is possible to craft graphics which are rendered in exponential time relative to their size. This makes it very easy to stall firefox using only a tiny file. Additionally the SVG renderer seems to use exponential space too (presumably by precomputing the graph for fast re-rendering after zooming.) this causes firefox to allocate and use huge amounts of memory (on a 361 byte file.)

Reproducible: Always

Steps to Reproduce:
1. Visit http://www.cs.vu.nl/~ejbosman/death.svgz or a similarly crafted svg file

Actual Results:  
Firefox stalls, allocates huge amounts of memory. After a while, my system (Ubuntu Hardy) starts thrashing (preventable using ulimit of course,) becomes extremely unresponsive,

Expected Results:  
Rendering should not block menus/other tabs, if rendering takes too long, a message like the one for slow javascript programs should ask the user whether to continue.

The malicious SVG creates a huge tree of objects by recursively defining objects as groups of two links to the previous object,
Status: UNCONFIRMED → NEW
Component: Security → SVG
Ever confirmed: true
Keywords: perf, testcase
Product: Firefox → Core
QA Contact: firefox → general

Comment 2

11 years ago
Same behavior on Windows XP
OS: Linux → All
Flags: wanted1.9.2+

Comment 3

10 years ago
See also Bug 514841, about 10 MB animated GIF images that quickly eat up several gigabytes of memory when rendering, causing Firefox to become especially unresponsive on computers with smaller RAM installations (page-file thrashing).
Original testcase, slightly cleaned up and with proper indentation.
Test case, for comparison, which doesn't reproduce the symptom (at least, in my environment).
(In reply to comment #2)
> Same behavior on Windows XP

Same behavior on Windows Vista SP2 using a nightly build [1].

I've made a few experiments and, at least for me, the symptom goes away after commenting the groups after (and including) the one with the "m" identifier. It seems that the exponential symptom is triggered around here: uncommenting a group at a time makes the browser halt (and consume memory) for a while more than with the previous group subset.

I've also tried adding the "a" identifier to the existing circle, in order to check if this was only reproducible with broken links but no: making the target resource resolvable or not doesn't lead to a different result.


(In reply to comment #3)
> See also Bug 514841, about 10 MB animated GIF images that quickly eat up
> several gigabytes of memory when rendering

Sorry, Brandon, but this issue isn't apparently related with rendering, it's related with resource locating dependencies. ;-)


[1] Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.3a1pre) Gecko/20091029 Minefield/3.7a1pre (.NET CLR 3.5.30729)
(Reporter)

Comment 7

8 years ago
Since firefox 4, SVG is now also supported in <img> tags, this makes sites that
allow cross-linked PNGs (think forums/wikis) vulnerable to a client-side DOS.

See:

http://pizzadoos.com/forcesvg/death.html

(http://pizzadoos.com/forcesvg/death.png really is an SVG, with a forced image/svg+xml mime-type to demonstrate that checking on the extension by the webdeveloper won't help.)
Whiteboard: [use]
Whiteboard: [use] → [use] [external-report]
(In reply to Helder "Lthere" Magalhães from comment #4)
> Created attachment 409337 [details]
> Slightly modified testcase

tested for grins. The resulting crash is 
bp-aafb91ff-9855-4fca-b338-960852140718
 OOM | large | mozalloc_abort(char const* const) | mozalloc_handle_oom(unsigned int) | moz_xrealloc | nsTArray_base<nsTArrayInfallibleAllocator, nsTArray_CopyWithMemutils>::EnsureCapacity(unsigned int, unsigned int) | nsTArray_Impl<nsIContent*, nsTArray...
Duplicate of this bug: 1105796
I'm not certain, but I think that this bug  also poisons the Fx cache making it slow on startup. 


Could this please be fixed?
I have worked on this bug and here is what I've found.

The growth of memory happens during reflow.
To interrupt it, ProcessHangMonitor appears to be a good candidate. Indeed, it is already used for slow scripts and plugin hang. 
To use it, it is necessary to add a new hangType (SLOW_SVG_REFLOW for instance, see the diff file joined), and adapt several ProcessHangMonitor methods (the diff is probably not enough, and there are probably others modifications to do). 
I think it might be quite feasible to interrupt the growth during CreateAnonymousContent (https://dxr.mozilla.org/mozilla-central/source/layout/svg/nsSVGUseFrame.cpp#238), as this method is called a lot during the reflow of this file (but I did not manage to do it). 
The best solution would probably be to detect the growth of memory, but a timeout can be used too. WindowMemoryManager is probably useful to get the memory use of the process, but I didn't understand how it works. Otherwise, memory use can be accessed like shown in the code attached, but such methods are OS dependant (in this diff, it is done for linux and stops the growth by killing the process without any prompt). 
Once the growth is detected, we should show a dialog to the user, like it is done here for slow script : https://dxr.mozilla.org/mozilla-central/source/js/xpconnect/src/XPCJSRuntime.cpp#1480 
Then, if the user wants to stop the loading process, we should use the ProcessHangMonitor TerminateProcess method to stop it.
You will also find attached a new test case which doesn't increase the RAM as much as the original one (stops after a 1.6Go increase), which can be useful to see the RAM increasing “without” danger, and a gdb backtrace taken during the reflow.
Please note that the code that causes the increase is done in an independent process called Web Content in nightly, due to e10s implementation. For that reason, to see in gdb what is executed we have to attach it to this new process.

See my comments below for attachments

Updated

3 years ago
Duplicate of this bug: 1302267
You need to log in before you can comment on or make changes to this bug.