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