Bug 92904

Summary: Large amount of uninitialized values in svg parsing and processing
Product: cairo Reporter: gustavo.grieco
Component: svg backendAssignee: Emmanuel Pacaud <emmanuel.pacaud>
Status: RESOLVED MOVED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: critical    
Priority: medium    
Version: unspecified   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description gustavo.grieco 2015-11-11 17:09:53 UTC
**This is a copy of a security report, please make this bug private as soon as possible reproduced here since it affects cairo. After that, i will submit the test cases to reproduce it.**

Hello,

We detected a large amount of uninitialized values in the parsing and processing of svg files using librsvg and related libraries (e.g, libcairo) causing undefined behaviors. Some of these issues are originated in librsvg, some in libcairo and others (libpixman maybe). I haven't found a way to privately report these issues to the cairo developers but anyway i think you should be aware of this, since it affects almost every program using gdk-pixbuf (yes, including Firefox and Chromium when you try to attach a svg in Linux). These issues were tested in a fully updated Ubuntu 14.04 (with librsvg-2.40.2 and its dependencies). Other configurations/versions are likely affected.

Please find attached some small svg files to trigger the creation and use of initialized values. Valgrind reports are also attached. You can reproduce these issues using a gdk-pixbuf minimum example (available here: https://github.com/CIFASIS/QuickFuzz/blob/master/bins/gdk-pixbuf.c). These svg are taking forever to be rendered (possible infinite loop).

DoS is not the only possible attack: we also found that it is possible to use a state-of-the-art fuzzer, american fuzzy lop, to discover interesting crashes. In the instrumented mode, afl will look for new "transitions" in the control flow graph of a program. If you collect many different test cases, you can find some interesting ways of exploit uninitialized values (specially, in the stack). We used rsvg-convert process the test cases with the undefined behavior and after fuzzing for a few hours, afl detected this heap overflow:

Program received signal SIGSEGV, Segmentation fault.
rsvg_filter_primitive_erode_render (self=0x8115880, ctx=0x8162d10) at rsvg-filter.c:2495
2495                        output_pixels[y * rowstride + x * 4 + ch] = extreme;
(gdb) bt
#0  rsvg_filter_primitive_erode_render (self=0x8115880, ctx=0x8162d10) at rsvg-filter.c:2495
#1  0x080c0575 in rsvg_filter_primitive_render (ctx=0x8162d10, self=<optimized out>) at rsvg-filter.c:86
#2  rsvg_filter_render (self=0x81152e0, source=source@entry=0x8167608, context=context@entry=0x80fb330, bounds=bounds@entry=0x8124d34,
    channelmap=channelmap@entry=0x80ea460 "2103") at rsvg-filter.c:530
#3  0x080d78c9 in rsvg_cairo_pop_render_stack (ctx=0x80fb330) at rsvg-cairo-draw.c:806
#4  rsvg_cairo_pop_discrete_layer (ctx=0x80fb330) at rsvg-cairo-draw.c:853
#5  0x080ce488 in rsvg_node_use_draw (self=0x811fda0, ctx=0x80fb330, dominate=0) at rsvg-structure.c:228
#6  0x080ccef0 in rsvg_node_draw (dominate=0, ctx=0x80fb330, self=0x811fda0) at rsvg-structure.c:69
#7  _rsvg_node_draw_children (self=0x811f800, ctx=0x80fb330, dominate=0) at rsvg-structure.c:87
#8  0x080ccef0 in rsvg_node_draw (dominate=0, ctx=0x80fb330, self=0x811f800) at rsvg-structure.c:69
#9  _rsvg_node_draw_children (self=0x811b4b8, ctx=0x80fb330, dominate=0) at rsvg-structure.c:87
#10 0x080ccef0 in rsvg_node_draw (dominate=0, ctx=0x80fb330, self=0x811b4b8) at rsvg-structure.c:69
#11 _rsvg_node_draw_children (self=0x8113378, ctx=0x80fb330, dominate=0) at rsvg-structure.c:87
#12 0x080ccef0 in rsvg_node_draw (dominate=0, ctx=0x80fb330, self=0x8113378) at rsvg-structure.c:69
#13 _rsvg_node_draw_children (self=0x8111ea0, ctx=0x80fb330, dominate=0) at rsvg-structure.c:87
#14 0x080cd5d0 in rsvg_node_draw (dominate=0, ctx=0x80fb330, self=0x8111ea0) at rsvg-structure.c:69
#15 rsvg_node_svg_draw (self=0x81086e0, ctx=0x80fb330, dominate=0) at rsvg-structure.c:323
#16 0x080ceb60 in rsvg_node_draw (self=0x81086e0, ctx=0x80fb330, dominate=0) at rsvg-structure.c:69
#17 0x0808af0a in rsvg_handle_render_cairo_sub (id=0x0, cr=0x80fb900, handle=0x80ff8f0) at rsvg-cairo-render.c:225
#18 rsvg_handle_render_cairo (handle=handle@entry=0x80ff8f0, cr=cr@entry=0x80fb900) at rsvg-cairo-render.c:247
#19 0x0804ec8c in main (argc=1, argv=0xbffff6c4) at rsvg-convert.c:360

Unfortunately, such crash is difficult to reproduce in the original rsvg-convert binary (remember that afl needs to recompile to instrumenting binaries) but the uninitialized values are easy to spot using valgrind (such report is also attached). Nevertheless, the possibility of finding vulnerabilities is real and therefore these bugs should be fixed.

These test cases were found using QuickFuzz and afl.

Regards,
Gustavo.
Comment 1 Uli Schlachter 2015-11-13 09:52:11 UTC
Well, what do you want me to do with this report? The C program you link to "just" renders SVGs and the SVG files which you claim to attach aren't attached. Just saying that somewhere there is a use of undefined variable that causes malfunction in cairo doesn't really help me.

And yes, you say that you will attach the files after the bug was marked private. Sadly I don't think I have more rights in bugzilla than you do. And, as far as I know, firefox bundles their own (ancient?) copy of cairo anyway, so having a fixed cairo version won't help firefox immediately anyway.

I can see why you don't want to provide the SVG files. How about a list of uninitialized variables? (With git commit id, file name, line, or something like that) Or alternatively a patch which initializes these variables? (That should turn this problem into NULL pointer dereferences which should be "less severe" and unitialized variables should be easy to initialize to NULL / 0 / 0.0 / whatever)
Comment 2 gustavo.grieco 2015-11-13 11:51:41 UTC
> Well, what do you want me to do with this report? The C program you link to "just" renders SVGs and the SVG files which you claim to attach aren't attached. Just saying that somewhere there is a use of undefined variable that causes malfunction in cairo doesn't really help me.

> And yes, you say that you will attach the files after the bug was marked private. Sadly I don't think I have more rights in bugzilla than you do. And, as far as I know, firefox bundles their own (ancient?) copy of cairo anyway, so having a fixed cairo version won't help firefox immediately anyway.

This bug is affecting Firefox in because they use gdk-pixbuf in the open-file dialog box to render a preview of the image that can fail if you browse a directory with a malicious image. Also, as far as i know, they are not using an ancient version of cairo. The version of cairo used here depends on gdk-pixbuf, which is the last version in the Ubuntu 14.04 repositories (1.13)

> I can see why you don't want to provide the SVG files. How about a list of uninitialized variables? (With git commit id, file name, line, or something like that) Or alternatively a patch which initializes these variables? (That should turn this problem into NULL pointer dereferences which should be "less severe" and unitialized variables should be easy to initialize to NULL / 0 / 0.0 / whatever)

I shared these test cases with the Mozilla security team and they have a private bug, so it is better to keep them private for now. I can send them to to your private email if you want.
Comment 3 Adrian Johnson 2015-11-17 07:00:42 UTC
You can find the version of cairo in firefox by printing a page to a file in pdf format and using pdfinfo (or a pdf viewer that shows pdf properties) to show the cairo version.

Using Firefox in Ubuntu 15.10 to print to a pdf and checking with pdfinfo I get:

$ pdfinfo file.pdf 
Creator:        cairo 1.9.5 (http://cairographics.org)
Producer:       cairo 1.9.5 (http://cairographics.org)
Tagged:         no
UserProperties: no
Suspects:       no
Form:           none
JavaScript:     no
Pages:          18
Encrypted:      no
Page size:      595.3 x 841.9 pts (A4)
Page rot:       0
File size:      1284826 bytes
Optimized:      no
PDF version:    1.5

So I would say yes they are still using an ancient version of cairo.
Comment 4 GitLab Migration User 2018-08-25 13:58:00 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/292.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.