6909597: Sun Java Runtime Environment JPEGImageReader stepX Integer Overflow Vulnerability
authorbae
Wed, 17 Feb 2010 13:32:26 +0300
changeset 5189 4909c522e208
parent 5188 6208e3cf4275
child 5190 efdb957bacbe
6909597: Sun Java Runtime Environment JPEGImageReader stepX Integer Overflow Vulnerability Reviewed-by: igor
jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Wed Feb 17 13:10:26 2010 +0300
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Wed Feb 17 13:32:26 2010 +0300
@@ -258,6 +258,7 @@
 
 typedef struct pixelBufferStruct {
     jobject hpixelObject;   // Usually a DataBuffer bank as a byte array
+    unsigned int byteBufferLength;
     union pixptr {
         INT32         *ip;  // Pinned buffer pointer, as 32-bit ints
         unsigned char *bp;  // Pinned buffer pointer, as bytes
@@ -270,6 +271,7 @@
  */
 static void initPixelBuffer(pixelBufferPtr pb) {
     pb->hpixelObject = NULL;
+    pb->byteBufferLength = 0;
     pb->buf.ip = NULL;
 }
 
@@ -279,13 +281,13 @@
  */
 static int setPixelBuffer(JNIEnv *env, pixelBufferPtr pb, jobject obj) {
     pb->hpixelObject = (*env)->NewGlobalRef(env, obj);
-
     if (pb->hpixelObject == NULL) {
         JNU_ThrowByName( env,
                          "java/lang/OutOfMemoryError",
                          "Setting Pixel Buffer");
         return NOT_OK;
     }
+    pb->byteBufferLength = (*env)->GetArrayLength(env, pb->hpixelObject);
     return OK;
 }
 
@@ -302,6 +304,7 @@
         unpinPixelBuffer(env, pb);
         (*env)->DeleteGlobalRef(env, pb->hpixelObject);
         pb->hpixelObject = NULL;
+        pb->byteBufferLength = 0;
     }
 }
 
@@ -1828,6 +1831,7 @@
     boolean orderedBands = TRUE;
     imageIODataPtr data = (imageIODataPtr) ptr;
     j_decompress_ptr cinfo;
+    unsigned int numBytes;
 
     /* verify the inputs */
 
@@ -2027,15 +2031,22 @@
                 // scanline buffer into the raster.
                 in = scanLinePtr + (sourceXStart * cinfo->output_components);
                 if (pixelLimit > in) {
-                    memcpy(out, in, pixelLimit - in);
+                    numBytes = pixelLimit - in;
+                    if (numBytes > data->pixelBuf.byteBufferLength) {
+                        numBytes = data->pixelBuf.byteBufferLength;
+                    }
+                    memcpy(out, in, numBytes);
                 }
             } else {
+                numBytes = numBands;
                 for (in = scanLinePtr+sourceXStart*cinfo->output_components;
-                     in < pixelLimit;
+                     in < pixelLimit &&
+                       numBytes <= data->pixelBuf.byteBufferLength;
                      in += pixelStride) {
                     for (i = 0; i < numBands; i++) {
                         *out++ = *(in+bands[i]);
                     }
+                    numBytes += numBands;
                 }
             }