Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6788196
Votes 0
Synopsis (porting) Bounds checks in io_util.c rely on undefined behaviour
Category java:classes_io
Reported Against
Release Fixed 7(b44), 6-open(b16) (Bug ID:2172689)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs
Submit Date 22-DEC-2008
Description
FULL PRODUCT VERSION :
java version "1.6.0_0"
OpenJDK Runtime Environment (build 1.6.0_0-b12)
OpenJDK Core VM (build 14.0-b08, interpreted mode)
(built from icedtea6-ce9956fe8908)

ADDITIONAL OS VERSION INFORMATION :
All platforms

A DESCRIPTION OF THE PROBLEM :
In jdk/src/share/native/java/io/io_util.c, both readBytes and writeBytes include the following array bounds check:

  if ((off < 0) || (off > datalen) ||
      (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
         JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
         return -1;
     }

off, len and datalen are all signed 32-bit integers.  The result of (off + len) is undefined in C if the result overflows, which can cause the exception not to be thrown. This causes testsuite failures on 32-bit Linux PowerPC on Fedora 10.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the test case and run it on 32-bit Linux PowerPC on Fedora 10.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Exception in thread "main" java.lang.IndexOutOfBoundsException
	at java.io.FileInputStream.readBytes(Native Method)
	at java.io.FileInputStream.read(FileInputStream.java:236)
	at Test.main(Test.java:5)

ACTUAL -
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
	at java.io.FileInputStream.readBytes(Native Method)
	at java.io.FileInputStream.read(FileInputStream.java:236)
	at Test.main(Test.java:5)

Note that the thrown exception is different; I'm guessing it comes from the (*env)->SetByteArrayRegion further down readBytes.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.FileInputStream;
class Test {
  public static void main(String[] args) throws Exception {
    byte[] b = new byte[20];
    (new FileInputStream("/bin/ls")).read(b, 1, 0x7fffffff);
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
http://icedtea.classpath.org/hg/icedtea6/file/ce9956fe8908/patches/icedtea-io_util-overflow.patch
Posted Date : 2008-12-22 18:56:23.0
Work Around
N/A
Evaluation
The submitter is correct and this code is not portable. This bounds check has existed since at least jdk1.2. The proposed fix casts to uint32_t. An alternative is to change the check to:

--- a/src/share/native/java/io/io_util.c        Wed Dec 10 14:03:15 2008 -0800
+++ b/src/share/native/java/io/io_util.c        Tue Dec 23 20:07:06 2008 +0000
@@ -74,8 +74,7 @@ readBytes(JNIEnv *env, jobject this, jby
     }
     datalen = (*env)->GetArrayLength(env, bytes);

-    if ((off < 0) || (off > datalen) ||
-        (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
+    if ((off < 0) || (len < 0) || (len > (datalen - off))) {
         JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
         return -1;
     }
@@ -147,8 +146,7 @@ writeBytes(JNIEnv *env, jobject this, jb
     }
     datalen = (*env)->GetArrayLength(env, bytes);

-    if ((off < 0) || (off > datalen) ||
-        (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
+    if ((off < 0) || (len < 0) || (len > (datalen - off))) {
         JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
         return;
     }
Posted Date : 2008-12-23 20:12:09.0

Martin plans to push a change-set for this, see discussion at:
http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-December/000955.html
http://mail.openjdk.java.net/pipermail/core-libs-dev/2009-January/000967.html
Posted Date : 2009-01-07 09:08:00.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang