I. BACKGROUND

http://en.wikipedia.org/wiki/JavaSE
http://openjdk.java.net/projects/jdk7u/
http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk  // Java and native sources


II. DESCRIPTION

The vulnerable Java's ShortComponentRaster.verify() method allows to bypass all
"dataOffsets[]" boundary checks when the "numDataElements" field is 0:

    // sun.awt.image.ShortComponentRaster
    protected final void verify() {
        for (int i = 0; i < dataOffsets.length; i++) {
            if (dataOffsets[i] < 0) {
                throw new RasterFormatException("Data offsets for band " + i + "(" + dataOffsets[i] + ") must be >= 0");
            }
        }

        int maxSize = 0;
        int size;

        // we can be sure that width and height are greater than 0
        if (scanlineStride < 0 || scanlineStride > (Integer.MAX_VALUE / height))
        {
            // integer overflow
            throw new RasterFormatException("Incorrect scanline stride: " + scanlineStride);
        }
        int lastScanOffset = (height - 1) * scanlineStride;

        if (pixelStride < 0 || pixelStride > (Integer.MAX_VALUE / width))
        {
            // integer overflow
            throw new RasterFormatException("Incorrect pixel stride: " + pixelStride);
        }
        int lastPixelOffset = (width - 1) * pixelStride;

        if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
            // integer overflow
            throw new RasterFormatException("Incorrect raster attributes");
        }
        lastPixelOffset += lastScanOffset;

        for (int i = 0; i < numDataElements; i++) {
            size = lastPixelOffset + dataOffsets[i];
            if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
                throw new RasterFormatException("Incorrect band offset: " + dataOffsets[i]);
            }
            if (size > maxSize) {
                maxSize = size;
            }
        }
        if (data.length < maxSize) {
            throw new RasterFormatException("Data array too small (should be " + maxSize + " )");
        }
    }   

"dataOffsets[]" can be out of bounds of the real data storage due to the fact
that DataBufferUShort() constructor is vulnerable to the signed integer overflow 
and allows to set arbitrary "offsets[]" field values: 

    // java.awt.image.DataBufferUShort
    public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
        super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
        if (dataArray == null) {
            throw new NullPointerException("dataArray is null");
        }
        for (int i=0; i < dataArray.length; i++) {
            if (dataArray[i] == null) {
                throw new NullPointerException("dataArray["+i+"] is null");
            }
            if ((size+offsets[i]) > dataArray[i].length) {
                throw new IllegalArgumentException("Length of dataArray["+i+
                                                   "] is less than size+"+
                                                   "offsets["+i+"].");
            }
        }
        bankdata = (short[][]) dataArray.clone();
        data = bankdata[0];
    }

BufImgSurfaceData.createDataSC() stores raster's parameters for the further
usage within the native code: 

    // sun.awt.image.BufImgSurfaceData
    public static SurfaceData createDataSC(BufferedImage bImg,
                                           SurfaceType sType,
                                           IndexColorModel icm) {
        ShortComponentRaster scRaster =
            (ShortComponentRaster)bImg.getRaster();
        BufImgSurfaceData bisd =
            new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType);
        bisd.initRaster(scRaster.getDataStorage(),
                        scRaster.getDataOffset(0) * 2, 0,
                        scRaster.getWidth(),
                        scRaster.getHeight(),
                        scRaster.getPixelStride() * 2,
                        scRaster.getScanlineStride() * 2,
                        icm);
        return bisd;
    }


III. ANALYSIS

This vulnerability allows remote attackers to execute arbitrary code on vulnerable 
installations of Oracle Java. User interaction is required to exploit this 
vulnerability in that the target must visit a malicious page or open a malicious file.



IV. DETECTION
Oracle Java SE 6,7
