Heap overflow and DoS in librsvg-2

RESOLVED WORKSFORME

Status

()

Core
Widget: Gtk
RESOLVED WORKSFORME
2 years ago
2 years ago

People

(Reporter: Gustavo Grieco, Unassigned)

Tracking

({sec-vector})

41 Branch
Unspecified
Linux
sec-vector
Points:
---
Bug Flags:
sec-bounty -

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [gfx-noted])

Attachments

(2 attachments)

(Reporter)

Description

2 years ago
Created attachment 8666658 [details]
overflow.svg.gz

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0
Build ID: 20150918100310

Steps to reproduce:

Hi,

A heap overflow was found in the librsvg2: an out-of-band read is performed in the parsing of a svg file. This issue can be triggered opening or attaching files in Firefox 41 as well as other programs using librsvg2 (e.g. gdk-pixbuf). It was tested in Ubuntu 14.04 (x86_64). Also, a DoS is possible causing stack exhaustion. It looks like a circular SVG reference to me.


Actual results:

A detailed backtrace of the heap overflow is here (using imagemagick, but you can verify it in Firefox using gdb as well):

$ valgrind identify overflow.svg

==5650== Invalid read of size 8
==5650==    at 0x9884804: _rsvg_node_poly_set_atts (rsvg-shapes.c:175)
==5650==    by 0x988D7FE: rsvg_standard_element_start (rsvg-base.c:1958)
==5650==    by 0x9890B2A: rsvg_start_element (rsvg-base.c:651)
==5650==    by 0xA03C934: xmlParseStartTag (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0xA049E12: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0xA04AE1D: xmlParseChunk (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0x989015F: rsvg_handle_write (rsvg-base.c:1126)
==5650==    by 0x9664930: ??? (in /usr/lib/x86_64-linux-gnu/ImageMagick-6.7.7/modules-Q16/coders/svg.so)
==5650==    by 0x4EB5DEA: ReadImage (in /usr/lib/x86_64-linux-gnu/libMagickCore.so.5.0.0)
==5650==    by 0x4FD2D18: ReadStream (in /usr/lib/x86_64-linux-gnu/libMagickCore.so.5.0.0)
==5650==    by 0x4EB5950: PingImage (in /usr/lib/x86_64-linux-gnu/libMagickCore.so.5.0.0)
==5650==    by 0x4EB5B7A: PingImages (in /usr/lib/x86_64-linux-gnu/libMagickCore.so.5.0.0)
==5650==  Address 0x8cb2578 is 0 bytes after a block of size 4,824 alloc'd
==5650==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5650==    by 0x7A01610: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==5650==    by 0x9872D5F: rsvg_css_parse_number_list (rsvg-css.c:730)
==5650==    by 0x988472D: _rsvg_node_poly_set_atts (rsvg-shapes.c:153)
==5650==    by 0x988D7FE: rsvg_standard_element_start (rsvg-base.c:1958)
==5650==    by 0x9890B2A: rsvg_start_element (rsvg-base.c:651)
==5650==    by 0xA03C934: xmlParseStartTag (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0xA049E12: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0xA04AE1D: xmlParseChunk (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1)
==5650==    by 0x989015F: rsvg_handle_write (rsvg-base.c:1126)
==5650==    by 0x9664930: ??? (in /usr/lib/x86_64-linux-gnu/ImageMagick-6.7.7/modules-Q16/coders/svg.so)
==5650==    by 0x4EB5DEA: ReadImage (in /usr/lib/x86_64-linux-gnu/libMagickCore.so.5.0.0)

The DoS can be triggered opening or attaching a svg file. A detailed backtrace is here:

#0  0x00007ffff6e14295 in round_and_return (retval=retval@entry=0x7fffff7ff0f0, exponent=<optimized out>, exponent@entry=0, 
    negative=negative@entry=0, round_limb=round_limb@entry=0, round_bit=<optimized out>, round_bit@entry=0, more_bits=<optimized out>, 
    more_bits@entry=0) at strtod_l.c:338
#1  0x00007ffff6e154eb in __GI_____strtod_l_internal (nptr=<optimized out>, endptr=<optimized out>, group=<optimized out>, loc=<optimized out>)
    at strtod_l.c:1333
#2  0x00007fffc2ecfdb7 in rsvg_css_parse_raw_length (relative_size=<puntero sintético>, ex=<puntero sintético>, em=<puntero sintético>, 
    percent=<puntero sintético>, in=<puntero sintético>, str=str@entry=0x7fffc2ef3910 "1") at rsvg-css.c:116
#3  _rsvg_css_parse_length (str=str@entry=0x7fffc2ef3910 "1") at rsvg-css.c:189
#4  0x00007fffc2ee8478 in rsvg_state_init (state=state@entry=0x7fff84a1a160) at rsvg-styles.c:125
#5  0x00007fffc2ee9be0 in rsvg_state_push (ctx=ctx@entry=0x7fffc2b03480) at rsvg-styles.c:1586
#6  0x00007fffc2ef06ff in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fff84b95000)
    at rsvg-cairo-draw.c:680
#7  rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#8  rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#9  0x00007fffc2ef070c in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fff84b94000)
    at rsvg-cairo-draw.c:681
#10 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#11 rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#12 0x00007fffc2ef070c in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fff84b93000)
    at rsvg-cairo-draw.c:681
#13 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#14 rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#15 0x00007fffc2ef070c in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fff84b92000)
    at rsvg-cairo-draw.c:681
#16 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#17 rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#18 0x00007fffc2ef070c in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fff84b91000)
    at rsvg-cairo-draw.c:681
#19 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
(...)
#86500 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#86501 rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#86502 0x00007fffc2ef070c in rsvg_cairo_generate_mask (bbox=<optimized out>, ctx=0x7fffc2b03480, self=0x7fffc0c1e230, cr=0x7fffc365d000)
    at rsvg-cairo-draw.c:681
#86503 rsvg_cairo_pop_render_stack (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:828
#86504 rsvg_cairo_pop_discrete_layer (ctx=0x7fffc2b03480) at rsvg-cairo-draw.c:853
#86505 0x00007fffc2ee5aa0 in rsvg_node_use_draw (self=<optimized out>, ctx=0x7fffc2b03480, dominate=<optimized out>) at rsvg-structure.c:228
#86506 0x00007fffc2ee5503 in rsvg_node_draw (self=0x7fffc0c1e2c0, ctx=0x7fffc2b03480, dominate=<optimized out>) at rsvg-structure.c:69
#86507 0x00007fffc2ee5903 in rsvg_node_svg_draw (self=0x7fffbbf41e80, ctx=0x7fffc2b03480, dominate=<optimized out>) at rsvg-structure.c:323
#86508 0x00007fffc2ee5503 in rsvg_node_draw (self=0x7fffbbf41e80, ctx=0x7fffc2b03480, dominate=<optimized out>) at rsvg-structure.c:69
#86509 0x00007fffc2ef1ac3 in rsvg_handle_render_cairo_sub (handle=handle@entry=0x7fffdb590520, cr=cr@entry=0x7fffc365d000, id=id@entry=0x0)
    at rsvg-cairo-render.c:225
#86510 0x00007fffc2ef1ef4 in rsvg_handle_get_pixbuf_sub (handle=0x7fffdb590520, id=id@entry=0x0) at rsvg.c:90
#86511 0x00007fffc2ef1f77 in rsvg_handle_get_pixbuf (handle=<optimized out>) at rsvg.c:119
#86512 0x00007fffc30fde46 in gdk_pixbuf__svg_image_stop_load (data=0x7fffbcf0e9d0, error=0x0) at io-svg.c:160
#86513 0x00007fffedf26212 in generic_load_incrementally (module=0x7fffd738b350, f=0x7fffbcf27800, error=0x0) at gdk-pixbuf-io.c:1009
#86514 0x00007fffedf27b42 in gdk_pixbuf_new_from_file (filename=0x7fffc27f8ec0 "/home/g/Data/ef/librsvg-2/i.svg.1457671241152647490", error=0x0)
    at gdk-pixbuf-io.c:1096
#86515 0x00007ffff273caf3 in ?? () from /usr/lib/firefox/libxul.so
#86516 0x00007fffef4e63b8 in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86517 0x00007fffef4f7d3d in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86518 0x00007fffef4ffa29 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86519 0x00007fffef500212 in g_signal_emit_by_name () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86520 0x00007fffef4e63b8 in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86521 0x00007fffef4f7d3d in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86522 0x00007fffef4ffa29 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86523 0x00007fffef500212 in g_signal_emit_by_name () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86524 0x00007fffef4e63b8 in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86525 0x00007fffef4f7d3d in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86526 0x00007fffef4ffa29 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86527 0x00007fffef500212 in g_signal_emit_by_name () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86528 0x00007fffeec680e7 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86529 0x00007fffeec6b3f0 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86530 0x00007fffef4e65e7 in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86531 0x00007fffef4ff088 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86532 0x00007fffef4ffce2 in g_signal_emit () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
---Type <return> to continue, or q <return> to quit---
#86533 0x00007fffeedb32be in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86534 0x00007fffeedb7868 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86535 0x00007fffeecbf815 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86536 0x00007fffef4e63b8 in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86537 0x00007fffef4f7afb in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86538 0x00007fffef4ff6f9 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86539 0x00007fffef4ffce2 in g_signal_emit () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#86540 0x00007fffeedcf684 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86541 0x00007fffeecbdfc4 in gtk_propagate_event () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86542 0x00007fffeecbe37b in gtk_main_do_event () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#86543 0x00007fffee3a41ec in ?? () from /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
#86544 0x00007fffef216e04 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#86545 0x00007fffef217048 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#86546 0x00007fffef2170ec in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#86547 0x00007ffff273c8d6 in ?? () from /usr/lib/firefox/libxul.so
#86548 0x00007ffff2724bb7 in ?? () from /usr/lib/firefox/libxul.so
#86549 0x00007ffff2724ce6 in ?? () from /usr/lib/firefox/libxul.so
#86550 0x00007ffff17225f3 in ?? () from /usr/lib/firefox/libxul.so
#86551 0x00007ffff1739298 in ?? () from /usr/lib/firefox/libxul.so
#86552 0x00007ffff18ecedb in ?? () from /usr/lib/firefox/libxul.so
#86553 0x00007ffff18ddc8f in ?? () from /usr/lib/firefox/libxul.so
#86554 0x00007ffff271f5d7 in ?? () from /usr/lib/firefox/libxul.so
#86555 0x00007ffff2c7aae2 in ?? () from /usr/lib/firefox/libxul.so
#86556 0x00007ffff2cb08ba in ?? () from /usr/lib/firefox/libxul.so
#86557 0x00007ffff2cb0bab in ?? () from /usr/lib/firefox/libxul.so
#86558 0x00007ffff2cb0e2b in XRE_main () from /usr/lib/firefox/libxul.so
#86559 0x0000555555558fe1 in _start ()


Expected results:

It shouldn't read out of the heap buffer nor crash.
(Reporter)

Comment 1

2 years ago
Created attachment 8666659 [details]
i.svg.1457671241152647490.gz
(Reporter)

Updated

2 years ago
OS: Unspecified → Linux

Comment 2

2 years ago
I'm confused, librsvg doesn't seem to be in our source tree - is this only on builds that aren't official mozilla builds and use the relevant switch to link this in?
Flags: needinfo?(gustavo.grieco)
(Reporter)

Comment 3

2 years ago
librsvg is used as a image loader from gdk-pixbuf, which is directly used by Firefox in Linux. This issue is related to https://bugzilla.mozilla.org/show_bug.cgi?id=1203078 (you can check the discussion)
Flags: needinfo?(gustavo.grieco)

Updated

2 years ago
Group: firefox-core-security → core-security
Component: Untriaged → Widget: Gtk
Product: Firefox → Core

Updated

2 years ago
Blocks: 1203078
Whiteboard: [gfx-noted]
I'm not sure there's anything that can really be done about this, since we already ran into the problem that removing SVG support will cause regressions with most GTK3 and GNOME themes, so is not an option.

Maybe as a pie-in-the-sky workaround we could just replace gdk-pixbuf's image loaders with our own that route to image lib, but that's a significantly large reworking for little gain.

I think it might be best to just file an upstream bug report with the librsvg folks and see if it can't get fixed on their end...
(Reporter)

Comment 5

2 years ago
> I think it might be best to just file an upstream bug report with the librsvg folks and see if it can't get fixed on their end...

I sent a similar report to the gnome security email. I don't know if Firefox should do something about this, but i think it was important to report security issues in librsvg2. I'm still running the fuzzer, to know if there are more critical issues there..
Flags: sec-bounty?
Keywords: sec-moderate
Group: core-security → layout-core-security
(Reporter)

Comment 6

2 years ago
Uhm, it seems that the gnome developers are still working on these bugs. In the meantime.. isn't possible to temporary disable svg during the opening of files?

Comment 7

2 years ago
(In reply to Lee Salzman [:eihrul] from comment #4)
> I'm not sure there's anything that can really be done about this, since we
> already ran into the problem that removing SVG support will cause
> regressions with most GTK3 and GNOME themes, so is not an option.

Maybe this is a dumb question, but can we not disable it only for non chrome: URIs?

Comment 8

2 years ago
(In reply to :Gijs Kruitbosch from comment #7)
> (In reply to Lee Salzman [:eihrul] from comment #4)
> > I'm not sure there's anything that can really be done about this, since we
> > already ran into the problem that removing SVG support will cause
> > regressions with most GTK3 and GNOME themes, so is not an option.
> 
> Maybe this is a dumb question, but can we not disable it only for non
> chrome: URIs?

... and the gtk icon stuff, I guess.
(In reply to :Gijs Kruitbosch from comment #8)
> (In reply to :Gijs Kruitbosch from comment #7)
> > (In reply to Lee Salzman [:eihrul] from comment #4)
> > > I'm not sure there's anything that can really be done about this, since we
> > > already ran into the problem that removing SVG support will cause
> > > regressions with most GTK3 and GNOME themes, so is not an option.
> > 
> > Maybe this is a dumb question, but can we not disable it only for non
> > chrome: URIs?
> 
> ... and the gtk icon stuff, I guess.

In principle it is possible to selectively disable it for opening files, but it is a bit painful since it needs to be disabled and then re-enabled every time you preview a file.

It is a question of whether it is justified given the limited impact (you have to specifically click on the file after trying to open it in the file chooser) and that upstream may just fix the issues. 

Can't do it for icons because we need those for GTK themes. SVG is too commonly used there.
(Reporter)

Updated

2 years ago
See Also: → bug 1222533
(Reporter)

Comment 10

2 years ago
These issues are solved in this librsvg revision:

https://git.gnome.org/browse/librsvg/commit/?id=0cfdd27ecb5023b65865d6458d9a810f48f08eb2

but there is still no official release.
(Reporter)

Comment 11

2 years ago
This is finally fixed in librsvg 2.40.13. I guess you can close it now.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → INVALID
Flags: sec-bounty? → sec-bounty-
Keywords: sec-moderate → sec-vector
Resolution: INVALID → WORKSFORME

Updated

2 years ago
See Also: → bug 1275902
Group: layout-core-security
You need to log in before you can comment on or make changes to this bug.