ref: d379be4ca803bf0bdd43d00b89da320c29d393c4
parent: 3f370a0ffaa5dd8b903b0ee36294529fbf0cbd1f
author: zeniko <zeniko@gmail.com>
date: Fri Jul 5 09:11:58 EDT 2013
Bug 694111: prevent heap overflow jbig2_image_compose fails to ensure that the destination rectangle lies entirely within the destination buffer (in the case of the file 3324.pdf.asan.50.2585, this happens due to a huge value for y). Adding a new check which makes sure that... @ y * dst->stride + leftbyte doesn't overflow @ x and leftbyte don't overflow to the next line @ h * dst->stride doesn't overflow @ all values read are within the destination buffer The file 3324.pdf.asan.50.2585 also demonstrates a memory leak where the glyph isn't properly released if jbig2_image_compose fails.
--- a/jbig2_image.c
+++ b/jbig2_image.c
@@ -256,9 +256,6 @@
#endif
leftbyte = x >> 3;
- if (leftbyte > dst->height * dst->stride)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
- "preventing heap overflow in jbig2_image_compose");
rightbyte = (x + w - 1) >> 3;
shift = x & 7;
@@ -265,6 +262,11 @@
/* general OR case */
s = ss;
d = dd = dst->data + y*dst->stride + leftbyte;
+ if (d < dst->data || leftbyte > dst->stride || h * dst->stride < 0 ||
+ d - leftbyte + h * dst->stride > dst->data + dst->height * dst->stride) {
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "preventing heap overflow in jbig2_image_compose");
+ }
if (leftbyte == rightbyte) {
mask = 0x100 - (0x100 >> w);
for (j = 0; j < h; j++) {
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -381,7 +381,10 @@
memcpy(rparams.grat, params->sbrat, 4);
code = jbig2_decode_refinement_region(ctx, segment,
&rparams, as, refimage, GR_stats);
- if (code < 0) goto cleanup2;
+ if (code < 0) {
+ jbig2_image_release(ctx, refimage);
+ goto cleanup2;
+ }
IB = refimage;
jbig2_image_release(ctx, IBO);
@@ -428,7 +431,10 @@
params->SBNUMINSTANCES);
#endif
code = jbig2_image_compose(ctx, image, IB, x, y, params->SBCOMBOP);
- if (code < 0) goto cleanup2;
+ if (code < 0) {
+ jbig2_image_release(ctx, IB);
+ goto cleanup2;
+ }
/* (3c.x) */
if ((!params->TRANSPOSED) && (params->REFCORNER < 2)) {