Hi all, In C, the result of an overflowing add of two signed integers is undefined. The array bounds checks in readBytes and writeBytes in jdk/src/share/native/java/io/io_util.c, however, rely on the assumption that the result of the overflowing add will be negative. The attached patch fixes.
Cheers, Gary -- http://gbenson.net/
diff -r 201a75db9b35 openjdk/jdk/src/share/native/java/io/io_util.c --- openjdk/jdk/src/share/native/java/io/io_util.c Mon Dec 22 12:32:44 2008 +0000 +++ openjdk/jdk/src/share/native/java/io/io_util.c Mon Dec 22 12:48:49 2008 +0000 @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> +#include <assert.h> #include "jni.h" #include "jni_util.h" @@ -73,9 +74,10 @@ return -1; } datalen = (*env)->GetArrayLength(env, bytes); + assert(datalen >= 0); - if ((off < 0) || (off > datalen) || - (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) { + if ((off < 0) || (len < 0) || + (((uint32_t) off + (uint32_t) len) > (uint32_t) datalen)) { JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0); return -1; } @@ -146,9 +148,10 @@ return; } datalen = (*env)->GetArrayLength(env, bytes); + assert(datalen >= 0); - if ((off < 0) || (off > datalen) || - (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) { + if ((off < 0) || (len < 0) || + (((uint32_t) off + (uint32_t) len) > (uint32_t) datalen)) { JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0); return; }
/* @test * @bug 6788196 * @summary Check that file IO array bounds checks are applied */ import java.io.File; import java.io.FileInputStream; public class Test6788196 { public static void main(String[] args) throws Exception { File file = new File( System.getProperty("test.src", "."), "Test6779290.java"); FileInputStream fis = new FileInputStream(file); byte[] b = new byte[20]; try { fis.read(b, 10, Integer.MAX_VALUE); } catch (ArrayIndexOutOfBoundsException e) { throw e; } catch (IndexOutOfBoundsException e) { } } }