Package: libimager-perl
Version: 0.50-1
Severity: grave
Tags: security patch
Justification: user security hole

I'm the upstream maintainer for the Imager perl module.

The BMP reader in Imager 0.56 and earlier can cause a memory overflow
in a malloced() buffer when reading an 8-bit/pixel compressed image
where a literal or RLE run overflows the scan-line boundary.

This typically causes the program to exit with a glibc bug, but it may
also be possible to corrupt the memory arena in such a way as to
execute arbitrary code, though I don't see how.  At the very least
this could be a denial of service.

I've attached a patch that should apply to Imager 0.45 through 0.56
(with some fuzz).

I've released Imager 0.57 to CPAN which fixes this issue.

-- System Information:
Debian Release: 4.0
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-4-686
Locale: LANG=C, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)

Versions of packages libimager-perl depends on:
ii  libc6                     2.3.6.ds1-13   GNU C Library: Shared libraries
ii  libfreetype6              2.2.1-5        FreeType 2 font engine, shared lib
ii  libjpeg62                 6b-13          The Independent JPEG Group's JPEG 
ii  libpng12-0                1.2.15~beta5-1 PNG library - runtime
ii  libt1-5                   5.1.0-2        Type 1 font rasterizer library - r
ii  libtiff4                  3.8.2-7        Tag Image File Format (TIFF) libra
ii  libungif4g                4.1.4-4        shared library for GIF images
ii  perl                      5.8.8-7        Larry Wall's Practical Extraction 
ii  perl-base [perlapi-5.8.8] 5.8.8-7        The Pathologically Eclectic Rubbis
ii  zlib1g                    1:1.2.3-13     compression library - runtime

libimager-perl recommends no packages.

-- no debconf information
Index: bmp.c
===================================================================
--- bmp.c	(revision 1210)
+++ bmp.c	(working copy)
@@ -916,6 +916,13 @@
         }
       }
       else if (packed[0]) {
+	if (x + packed[0] > xsize) {
+	  /* this file is corrupt */
+	  myfree(line);
+	  i_push_error(0, "invalid data during decompression");
+	  i_img_destroy(im);
+	  return NULL;
+	}
         line[0] = packed[1] >> 4;
         line[1] = packed[1] & 0x0F;
         for (i = 0; i < packed[0]; i += 2) {
@@ -958,6 +965,13 @@
 
         default:
           count = packed[1];
+	  if (x + count > xsize) {
+	    /* this file is corrupt */
+	    myfree(line);
+	    i_push_error(0, "invalid data during decompression");
+	    i_img_destroy(im);
+	    return NULL;
+	  }
           size = (count + 1) / 2;
           read_size = (size+1) / 2 * 2;
           if (ig->readcb(ig, packed, read_size) != read_size) {
@@ -1113,6 +1127,13 @@
         }
       }
       if (packed[0]) {
+	if (x + packed[0] > xsize) {
+	  /* this file isn't incomplete, it's corrupt */
+	  myfree(line);
+	  i_push_error(0, "invalid data during decompression");
+	  i_img_destroy(im);
+	  return NULL;
+	}
         memset(line, packed[1], packed[0]);
         i_ppal(im, x, x+packed[0], y, line);
         x += packed[0];
@@ -1147,6 +1168,14 @@
 
         default:
           count = packed[1];
+	  if (x + count > xsize) {
+	    /* runs shouldn't cross a line boundary */
+	    /* this file isn't incomplete, it's corrupt */
+	    myfree(line);
+	    i_push_error(0, "invalid data during decompression");
+	    i_img_destroy(im);
+	    return NULL;
+	  }
           read_size = (count+1) / 2 * 2;
           if (ig->readcb(ig, line, read_size) != read_size) {
             myfree(line);

Reply via email to