Package: libcairo2
Version: cairo-1.14.0
Severity: normal
Tags: upstream patch

Dear Maintainer,

it is wrong to compute offsets like so:

   int rowstride = something;
   char *buffer = base_ptr + y*rowstride + x*4;

That idiom fails in 64bit architecture where integers are 32 bit.  Consider
that an A0 poster at 600 dpi brings a 19860x28080 image.  While width and
heights are 16 bit numbers, their product multiplied by a bpp of 4 results in a
negative integer.  Stride should be size_t, or, if it can be negative, long
integer.

The concept is illustrated by the last few lines of the gdb session I paste
below, which I used to find one of the patched locations.

$ gdb -q --args /usr/bin/inkscape -A test-pdf.pdf test-pdf.svg
Reading symbols from /usr/bin/inkscape...done.
(gdb) run
Starting program: /usr/bin/inkscape -A test-pdf.pdf test-pdf.svg
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-
sse2-unaligned.S:118
118     ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or
directory.
(gdb) up
#1  0x00007fffef68394d in memcpy (__len=<optimized out>, __src=<optimized out>,
__dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string3.h:51
51        return __builtin___memcpy_chk (__dest, __src, __len, __bos0
(__dest));
(gdb) up
#2  _cairo_image_surface_snapshot (abstract_surface=0x55555c6a61d0) at
.../../../../src/cairo-image-surface.c:792
792             memcpy (clone->data, image->data, clone->stride *
clone->height);
(gdb) whatis clone->stride
type = int
(gdb) p /x (size_t)(clone->stride * clone->height)
$1 = 0xffffffff85082c58
(gdb) p /x (size_t)((long)clone->stride * clone->height)
$2 = 0x85082c58
(gdb)



-- System Information:
Debian Release: 8.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
--- cairo-1.14.0.orig/src/cairo-image-surface.c
+++ cairo-1.14.0/src/cairo-image-surface.c
@@ -789,7 +789,7 @@ _cairo_image_surface_snapshot (void *abs
 	return &clone->base;
 
     if (clone->stride == image->stride) {
-	memcpy (clone->data, image->data, clone->stride * clone->height);
+	memcpy (clone->data, image->data, (long)clone->stride * clone->height);
     } else {
 	pixman_image_composite32 (PIXMAN_OP_SRC,
 				  image->pixman_image, NULL, clone->pixman_image,
Description: integer-overflow

--- cairo-1.14.0.orig/src/cairo-pdf-surface.c
+++ cairo-1.14.0/src/cairo-pdf-surface.c
@@ -2500,7 +2500,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf
 
     i = 0;
     for (y = 0; y < image->height; y++) {
-	pixel = (uint32_t *) (image->data + y * image->stride);
+	pixel = (uint32_t *) (image->data + (long)y * image->stride);
 
 	bit = 7;
 	for (x = 0; x < image->width; x++, pixel++) {

Reply via email to