After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 744391 - Fuzz: out-of-bounds write in sse2_fill called from cairo-image-compositor
Fuzz: out-of-bounds write in sse2_fill called from cairo-image-compositor
Status: RESOLVED OBSOLETE
Product: librsvg
Classification: Core
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: Federico Mena Quintero
librsvg maintainers
Depends on:
Blocks:
 
 
Reported: 2015-02-12 13:08 UTC by Atte Kettunen
Modified: 2017-12-13 18:06 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Atte Kettunen 2015-02-12 13:08:05 UTC
Tested on:

OS: Ubuntu 14.04

librsvg from github @ commit 400336480ed5abbe398d2fa646872a668205a5fd

reproducing file:

<svg vi="g"><rect  stroke="red" stroke-width="4294967294" width="20" height="10"/></svg>


stderr and ASAN-trace:

=================================================================
==3718==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61c00000f790 at pc 0x7f8905308972 bp 0x7fff12984530 sp 0x7fff12984528
WRITE of size 4 at 0x61c00000f790 thread T0
    #0 0x7f8905308971 in sse2_fill ??:0:0
    #1 0x7f89047a4807 in _pixman_implementation_fill ??:0:0
    #2 0x7f890313a24e in pixman_fill ??:0:0
    #3 0x7f890a99bfeb in fill_boxes ??:0:0
    #4 0x7f890ad24c0e in composite_aligned_boxes ??:0:0
    #5 0x7f890ad143c3 in clip_and_composite_boxes ??:0:0
    #6 0x7f890ad1177f in _cairo_spans_compositor_stroke ??:0:0
    #7 0x7f890a8f0716 in _cairo_compositor_stroke ??:0:0
    #8 0x7f890aa14c48 in _cairo_image_surface_stroke ??:0:0
    #9 0x7f890ad6b567 in _cairo_surface_stroke ??:0:0
    #10 0x7f890a9672bf in _cairo_gstate_stroke ??:0:0
    #11 0x7f890a91e34f in _cairo_default_context_stroke ??:0:0
    #12 0x7f890a895e7a in INT_cairo_stroke ??:0:0
    #13 0x7f890c5d92b3 in rsvg_cairo_render_path ??:0:0
    #14 0x7f890c5bffe4 in rsvg_render_path ??:0:0
    #15 0x7f890c553362 in _rsvg_node_rect_draw ??:0:0
    #16 0x7f890c55f5a6 in rsvg_node_draw ??:0:0
    #17 0x7f890c560147 in _rsvg_node_draw_children ??:0:0
    #18 0x7f890c55f5a6 in rsvg_node_draw ??:0:0
    #19 0x7f890c564c1c in rsvg_node_svg_draw ??:0:0
    #20 0x7f890c55f5a6 in rsvg_node_draw ??:0:0
    #21 0x7f890c5f19fb in rsvg_handle_render_cairo_sub ??:0:0
    #22 0x7f890c5f1d4e in rsvg_handle_render_cairo ??:0:0
    #23 0x4d525c in main ??:0:0
    #24 0x7f890930dec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287:0
    #25 0x418bd6 in _start ??:0:0

0x61c00000f790 is located 8 bytes to the right of 1800-byte region [0x61c00000f080,0x61c00000f788)
allocated by thread T0 here:
    #0 0x4ad153 in calloc _asan_rtl_:0
    #1 0x7f890409f487 in create_bits ??:0:0
    #2 0x7f890409dfd5 in _pixman_bits_image_init ??:0:0
    #3 0x7f89040a05fa in create_bits_image_internal ??:0:0
    #4 0x7f890409faaf in pixman_image_create_bits ??:0:0
    #5 0x7f890aa0a8d4 in _cairo_image_surface_create_with_pixman_format ??:0:0
    #6 0x7f890aa0b7be in INT_cairo_image_surface_create ??:0:0
    #7 0x4d47c6 in main ??:0:0
    #8 0x7f890930dec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287:0

Shadow bytes around the buggy address:
.
.
.
Comment 1 Atte Kettunen 2015-04-15 09:57:22 UTC
Any progress with this?
Comment 2 Federico Mena Quintero 2015-04-18 00:01:18 UTC
This happens here:

  • #0 sse2_fill
    at pixman-sse2.c line 3394
  • #1 _pixman_implementation_fill
    at pixman-implementation.c line 277
  • #2 pixman_fill
    at pixman.c line 766
  • #3 fill_boxes
    at cairo-image-compositor.c line 349
  • #4 composite_aligned_boxes
    at cairo-spans-compositor.c line 619
  • #5 clip_and_composite_boxes
    at cairo-spans-compositor.c line 873
  • #6 _cairo_spans_compositor_stroke
    at cairo-spans-compositor.c line 1029
  • #7 _cairo_compositor_stroke
    at cairo-compositor.c line 157
  • #8 _cairo_image_surface_stroke
    at cairo-image-surface.c line 961
  • #9 _cairo_surface_stroke
    at cairo-surface.c line 2210
  • #10 _cairo_gstate_stroke
    at cairo-gstate.c line 1185
  • #11 _cairo_default_context_stroke
    at cairo-default-context.c line 1013
  • #12 INT_cairo_stroke
    at cairo.c line 2146
  • #13 rsvg_cairo_render_path
    at rsvg-cairo-draw.c line 549
  • #14 rsvg_render_path
    at rsvg-base.c line 2023
  • #15 _rsvg_node_rect_draw
    at rsvg-shapes.c line 500
  • #16 rsvg_node_draw
    at rsvg-structure.c line 69
  • #17 rsvg_node_svg_draw
    at rsvg-structure.c line 323
  • #18 rsvg_node_draw
    at rsvg-structure.c line 69
  • #19 rsvg_handle_render_cairo_sub
    at rsvg-cairo-render.c line 225
  • #20 render_to_surface
    at test-display.c line 202
  • #21 main
    at test-display.c line 786

Note in frame #2 that pixman_fill() gets a height=-2, from

344                 for (i = 0; i < chunk->count; i++) {
345                     int x = _cairo_fixed_integer_part (chunk->base[i].p1.x);
346                     int y = _cairo_fixed_integer_part (chunk->base[i].p1.y);
347                     int w = _cairo_fixed_integer_part (chunk->base[i].p2.x) - x;
348                     int h = _cairo_fixed_integer_part (chunk->base[i].p2.y) - y;
349                     pixman_fill ((uint32_t *) dst->data,
350                                  dst->stride / sizeof (uint32_t),
351                                  PIXMAN_FORMAT_BPP (dst->pixman_format),
352                                  x, y, w, h, pixel);
353                 }

I think pixman_fill() should validate its arguments.  I'll try that.
Comment 3 Federico Mena Quintero 2015-04-20 23:40:09 UTC
I've made this bug visible to people who are not librsvg maintainers as well - for better visibility.  This doesn't seem easily exploitable.
Comment 4 Federico Mena Quintero 2015-04-20 23:44:19 UTC
For the upstream bug in Cairo, see https://bugs.freedesktop.org/show_bug.cgi?id=90120  That has a patch to check the arguments before calling pixman_fill().

The root cause of the problem is Cairo - it doesn't deal with big coordinates correctly and gets fixed-point overflow.

However, it's not completely clear to me where to install the "safety valve":

* Pixman should check the arguments to pixman_fill(), but it doesn't...

* ... or it should at least document the fact that it does no checking on arguments.

* It's Cairo's fault that pixman is getting invalid values; if Cairo cannot fix its overflow problems, at least it should have the safety valve itself.
Comment 5 GNOME Infrastructure Team 2017-12-13 18:06:48 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME'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.gnome.org/GNOME/librsvg/issues/102.