[PATCH] 6788196: Array bounds checks in io_util.c rely on undefined behaviour

Gary Benson gbenson at redhat.com
Tue Dec 23 10:21:19 UTC 2008


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/
-------------- next part --------------
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;
     }
-------------- next part --------------
/* @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) {
    }
  }
}


More information about the core-libs-dev mailing list