[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#832579: pixman: SIGSEGV after rowstride overflow in large image



Source: pixman
Version: 0.32.6
Severity: normal
Tags: patch

Dear Maintainer,

the following message was being written by dbg after launching evince on a pdf
containing a heavy image:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe5f92700 (LWP 32388)]
bits_image_fetch_bilinear_affine (repeat_mode=PIXMAN_REPEAT_PAD,
format=PIXMAN_x8r8g8b8, convert_pixel=<optimized out>, mask=0x7fffe5f8a5a0,
buffer=0x7fffe5f8a3a0,
    width=<optimized out>, line=<optimized out>, offset=<optimized out>,
image=0x7fffd00c4ea0) at ../../pixman/pixman-fast-path.c:2917

In order to understand the bug severity, consider that I obtained a large image
by exporting a 600dpi bitmap of an A0 poster.  Then I converted it to pdf.  I
brought an USB key with the resulting 170MB document to the print shop down the
road and got a hard copy.  Their plotter resolves 600dpi, and although it takes
a few minutes to load the file, producing that kind of files is still the most
practical approach, in my experience.

The nature of the bug is clear from the following excerpt:

(gdb) info locals
[...]
width = 19866
height = 28087
row1 = 0x7ffe8f375618 <error: Cannot access memory at address 0x7ffe8f375618>
row2 = 0x7ffe8f388c80 <error: Cannot access memory at address 0x7ffe8f388c80>

Indeed, after applying the patch I attach, evince works well.

Ale



-- System Information:
Debian Release: 8.5
  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)
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2911,8 +2911,8 @@
 	    repeat (repeat_mode, &x2, width);
 	    repeat (repeat_mode, &y2, height);
 
-	    row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
-	    row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
+	    row1 = (uint8_t *)bits->bits + (long)bits->rowstride * 4L * (long)y1;
+	    row2 = (uint8_t *)bits->bits + (long)bits->rowstride * 4L * (long)y2;
 
 	    tl = convert_pixel (row1, x1) | mask;
 	    tr = convert_pixel (row1, x2) | mask;

Reply to: