Red Hat Bugzilla – Bug 509531
CVE-2009-2295 ocaml-camlimages: PNG reader multiple integer overflows (oCERT-2009-009)
Last modified: 2009-10-16 06:03:26 EDT
oCERT advisory oCERT-2009-009 was published describing a flaw in ocaml-camlimages:
CamlImages, an open source image processing library, suffers from several
integer overflows which may lead to a potentially exploitable heap
overflow and result in arbitrary code execution.
The vulnerability is triggered by PNG image parsing, the read_png_file
and read_png_file_as_rgb24 functions do not properly validate the width
and height of the image. Specific PNG images with large width and height
can be crafted to trigger the vulnerability.
Issue was reported to affect both 2.2 and 3.0.1, which no upstream patch available at the moment.
I'll have a look at this one now.
Created attachment 350433 [details]
This is a potential fix which checks whether the
numbers we are about to multiply together could
provoke an arithmetic overflow (or are negative,
which would be equally bogus).
It solves the test case that I was given privately.
Note that in any case the bug only manifests on 32 bit
architectures. On 64 bit, the multiply does not
overflow, but unless you have loads of free memory
you will shortly afterwards get a (safe) Out_of_memory
(In reply to comment #4)
> Created an attachment (id=350433) [details]
One note from a very quick look... in general, test like:
(x) * (y) < (x) || (x) * (y) < (y)
is not sufficient to catch all possible integer overflows in multiplication. Think of x == y == 0x10001, x * y == 0x100020001, which is 0x20001 in 32bit world. This can still result in small buffer that may be overflown later.
The test is usually written as:
y != 0 && x > (TYPE)_MAX / y
(first part is needed if y can be 0, not needed in cases where y is sizeof(sometype)).
ocaml-camlimages-3.0.1-7.fc11.1 has been submitted as an update for Fedora 11.
ocaml-camlimages-3.0.1-3.fc10.1 has been submitted as an update for Fedora 10.
(In reply to comment #5)
> (In reply to comment #4)
> > Created an attachment (id=350433) [details] [details]
> > camlimages-oversized-png-check.patch
> One note from a very quick look... in general, test like:
> (x) * (y) < (x) || (x) * (y) < (y)
> is not sufficient to catch all possible integer overflows in multiplication.
> Think of x == y == 0x10001, x * y == 0x100020001, which is 0x20001 in 32bit
> world. This can still result in small buffer that may be overflown later.
> The test is usually written as:
> y != 0 && x > (TYPE)_MAX / y
> (first part is needed if y can be 0, not needed in cases where y is
Yup, someone just found a counterexample on #ocaml.
I'll change the patch and rebuild in a moment.
Created attachment 350440 [details]
Fix overflow detection in the patch.
I also see two occurrences of this in pngread.c:
row_pointers = (png_bytep*) stat_alloc(sizeof(png_bytep) * height);
While sizeof(png_bytep) is fixed, height comes from the file and it seems possible for it to be 2^32/4 or larger.
Created attachment 350441 [details]
Updated the patch with feedback from comment 10.
I've pushed new packages for Fedora 10, 11 and Rawhide
with the patch in comment 11.
Note that although we have CVS branches for EL-4 and EL-5,
we don't currently distribute this package (missing build dep).
However I've added the patch to those branches too, so that if
in future we build for EL-4/5 we will have the patch.
I've also discussed this issue and the patch with Debian and
Updates coming shortly.
ocaml-camlimages-3.0.1-3.fc10.2 has been submitted as an update for Fedora 10.
ocaml-camlimages-3.0.1-7.fc11.2 has been submitted as an update for Fedora 11.
Robert @ Gentoo reported that upstream fixed similar integer overflows in gifread.c and jpegread.c for values that are used in memory allocations and memcpy():
A stripped down [by Alexis Ballier] version of the patch is in Gentoo's BZ:
ocaml-camlimages-3.0.1-7.fc11.2 has been pushed to the Fedora 11 stable repository. If problems still persist, please make note of it in this bug report.
ocaml-camlimages-3.0.1-3.fc10.2 has been pushed to the Fedora 10 stable repository. If problems still persist, please make note of it in this bug report.
Long fixed ... Closing.