# HG changeset patch # User bae # Date 1266402746 -10800 # Node ID 4909c522e2081370c8df6130985f58f6cc2ce9f9 # Parent 6208e3cf42759d77740ff418b23db61503e6bb1f 6909597: Sun Java Runtime Environment JPEGImageReader stepX Integer Overflow Vulnerability Reviewed-by: igor diff -r 6208e3cf4275 -r 4909c522e208 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; } }