OpenJDK / lambda / lambda / jdk
changeset 10430:7ed340e7d894
7058602: BMP parser bugs found via zzuf fuzzing
Reviewed-by: prr, vadim
author | bae |
---|---|
date | Mon, 14 Oct 2013 15:32:29 +0400 |
parents | 124bffc749ea |
children | cb9fa40f73f7 |
files | src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java src/share/classes/com/sun/imageio/plugins/common/iio-plugin.properties src/share/classes/java/awt/image/ComponentSampleModel.java |
diffstat | 3 files changed, 95 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java Sat Oct 12 14:14:24 2013 -0700 +++ b/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java Mon Oct 14 15:32:29 2013 +0400 @@ -187,15 +187,24 @@ return 1; } + @Override public int getWidth(int imageIndex) throws IOException { checkIndex(imageIndex); - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } return width; } public int getHeight(int imageIndex) throws IOException { checkIndex(imageIndex); - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } return height; } @@ -205,7 +214,18 @@ } } - public void readHeader() throws IOException { + /** + * Process the image header. + * + * @exception IllegalStateException if source stream is not set. + * + * @exception IOException if image stream is corrupted. + * + * @exception IllegalArgumentException if the image stream does not contain + * a BMP image, or if a sample model instance to describe the + * image can not be created. + */ + protected void readHeader() throws IOException, IllegalArgumentException { if (gotHeader) return; @@ -307,6 +327,9 @@ case BI_RLE4: // 4-bit RLE compression // Read in the palette + if (bitmapOffset < (size + 14)) { + throw new IIOException(I18N.getString("BMPImageReader7")); + } int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries * 4; palette = new byte[sizeOfPalette]; @@ -375,7 +398,7 @@ break; default: throw new - RuntimeException(I18N.getString("BMPImageReader2")); + IIOException(I18N.getString("BMPImageReader2")); } } else if (size == 108 || size == 124) { // Windows 4.x BMP @@ -478,7 +501,7 @@ } } else { throw new - RuntimeException(I18N.getString("BMPImageReader3")); + IIOException(I18N.getString("BMPImageReader3")); } } @@ -660,7 +683,11 @@ public Iterator getImageTypes(int imageIndex) throws IOException { checkIndex(imageIndex); - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } ArrayList list = new ArrayList(1); list.add(new ImageTypeSpecifier(originalColorModel, originalSampleModel)); @@ -675,7 +702,11 @@ throws IOException { checkIndex(imageIndex); if (metadata == null) { - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } } return metadata; } @@ -686,7 +717,11 @@ public boolean isRandomAccessEasy(int imageIndex) throws IOException { checkIndex(imageIndex); - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } return metadata.compression == BI_RGB; } @@ -705,7 +740,11 @@ param = getDefaultReadParam(); //read header - readHeader(); + try { + readHeader(); + } catch (IllegalArgumentException e) { + throw new IIOException(I18N.getString("BMPImageReader6"), e); + } sourceRegion = new Rectangle(0, 0, 0, 0); destinationRegion = new Rectangle(0, 0, 0, 0); @@ -817,7 +856,7 @@ default: throw new - RuntimeException(I18N.getString("BMPImageReader1")); + IIOException(I18N.getString("BMPImageReader1")); } break; @@ -833,7 +872,7 @@ default: throw new - RuntimeException(I18N.getString("BMPImageReader1")); + IIOException(I18N.getString("BMPImageReader1")); } break; @@ -874,7 +913,7 @@ default: throw new - RuntimeException(I18N.getString("BMPImageReader1")); + IIOException(I18N.getString("BMPImageReader1")); } case VERSION_4_8_BIT: @@ -890,7 +929,7 @@ default: throw new - RuntimeException(I18N.getString("BMPImageReader1")); + IIOException(I18N.getString("BMPImageReader1")); } break;
--- a/src/share/classes/com/sun/imageio/plugins/common/iio-plugin.properties Sat Oct 12 14:14:24 2013 -0700 +++ b/src/share/classes/com/sun/imageio/plugins/common/iio-plugin.properties Mon Oct 14 15:32:29 2013 +0400 @@ -21,6 +21,8 @@ BMPImageReader3=New BMP version not implemented yet. BMPImageReader4=No ImageIO-style reader is found for BMPImageReader5=Input has not been set. +BMPImageReader6=Unable to read the image header. +BMPImageReader7=Invalid bitmap offset. BMPImageWriter0=Output is not an ImageOutputStream. BMPImageWriter1=The image region to be encoded is empty. BMPImageWriter2=Only 1 or 3 band image is encoded. @@ -34,7 +36,7 @@ BMPMetadata1=Metadata is read-only. -# WBMP plugin properties +# WBMP plugin properties WBMPImageReader0=Only one image exists in the stream. WBMPImageReader1=Input has not been set. WBMPImageReader2=Bad WBMP header.
--- a/src/share/classes/java/awt/image/ComponentSampleModel.java Sat Oct 12 14:14:24 2013 -0700 +++ b/src/share/classes/java/awt/image/ComponentSampleModel.java Mon Oct 14 15:32:29 2013 +0400 @@ -167,6 +167,7 @@ for (int i=0; i<numBands; i++) { bankIndices[i] = 0; } + verify(); } @@ -244,24 +245,53 @@ throw new IllegalArgumentException("Length of bandOffsets must "+ "equal length of bankIndices."); } + verify(); + } + + private void verify() { + int requiredSize = getBufferSize(); } /** * Returns the size of the data buffer (in data elements) needed * for a data buffer that matches this ComponentSampleModel. */ - private long getBufferSize() { + private int getBufferSize() { int maxBandOff=bandOffsets[0]; - for (int i=1; i<bandOffsets.length; i++) + for (int i=1; i<bandOffsets.length; i++) { maxBandOff = Math.max(maxBandOff,bandOffsets[i]); + } - long size = 0; - if (maxBandOff >= 0) - size += maxBandOff+1; - if (pixelStride > 0) - size += pixelStride * (width-1); - if (scanlineStride > 0) - size += scanlineStride*(height-1); + if (maxBandOff < 0 || maxBandOff > (Integer.MAX_VALUE - 1)) { + throw new IllegalArgumentException("Invalid band offset"); + } + + if (pixelStride < 0 || pixelStride > (Integer.MAX_VALUE / width)) { + throw new IllegalArgumentException("Invalid pixel stride"); + } + + if (scanlineStride < 0 || scanlineStride > (Integer.MAX_VALUE / height)) { + throw new IllegalArgumentException("Invalid scanline stride"); + } + + int size = maxBandOff + 1; + + int val = pixelStride * (width - 1); + + if (val > (Integer.MAX_VALUE - size)) { + throw new IllegalArgumentException("Invalid pixel stride"); + } + + size += val; + + val = scanlineStride * (height - 1); + + if (val > (Integer.MAX_VALUE - size)) { + throw new IllegalArgumentException("Invalid scan stride"); + } + + size += val; + return size; } @@ -409,7 +439,7 @@ public DataBuffer createDataBuffer() { DataBuffer dataBuffer = null; - int size = (int)getBufferSize(); + int size = getBufferSize(); switch (dataType) { case DataBuffer.TYPE_BYTE: dataBuffer = new DataBufferByte(size, numBanks);