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);