From: Vladimir Marko Date: Fri, 6 Nov 2015 16:57:03 +0000 (+0000) Subject: ART: Fix potential integer overflow in JNI. X-Git-Tag: android-x86-7.1-r1~852^2~80^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=795e341fff6c1984a34667c971a7153a8d63eb23;p=android-x86%2Fart.git ART: Fix potential integer overflow in JNI. Change-Id: I06fe2035f911cfc8537e27961c2dc2c7e4d1e20d --- diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 234a73396..415109fb0 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -1670,7 +1670,7 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); mirror::String* s = soa.Decode(java_string); - if (start < 0 || length < 0 || start + length > s->GetLength()) { + if (start < 0 || length < 0 || length > s->GetLength() - start) { ThrowSIOOBE(soa, start, length, s->GetLength()); } else { CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf); @@ -1684,7 +1684,7 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); mirror::String* s = soa.Decode(java_string); - if (start < 0 || length < 0 || start + length > s->GetLength()) { + if (start < 0 || length < 0 || length > s->GetLength() - start) { ThrowSIOOBE(soa, start, length, s->GetLength()); } else { CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf); @@ -2473,7 +2473,7 @@ class JNI { "GetPrimitiveArrayRegion", "get region of"); if (array != nullptr) { - if (start < 0 || length < 0 || start + length > array->GetLength()) { + if (start < 0 || length < 0 || length > array->GetLength() - start) { ThrowAIOOBE(soa, array, start, length, "src"); } else { CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf); @@ -2493,7 +2493,7 @@ class JNI { "SetPrimitiveArrayRegion", "set region of"); if (array != nullptr) { - if (start < 0 || length < 0 || start + length > array->GetLength()) { + if (start < 0 || length < 0 || length > array->GetLength() - start) { ThrowAIOOBE(soa, array, start, length, "dst"); } else { CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf); diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc index 41b368ec3..649df5f62 100644 --- a/runtime/jni_internal_test.cc +++ b/runtime/jni_internal_test.cc @@ -1077,6 +1077,12 @@ TEST_F(JniInternalTest, RegisterAndUnregisterNatives) { env_->set_region_fn(a, size - 1, size, nullptr); \ ExpectException(aioobe_); \ \ + /* Regression test against integer overflow in range check. */ \ + env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ + ExpectException(aioobe_); \ + env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ + ExpectException(aioobe_); \ + \ /* It's okay for the buffer to be null as long as the length is 0. */ \ env_->get_region_fn(a, 2, 0, nullptr); \ /* Even if the offset is invalid... */ \ @@ -1507,6 +1513,9 @@ TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { ExpectException(sioobe_); env_->GetStringRegion(s, 10, 1, nullptr); ExpectException(sioobe_); + // Regression test against integer overflow in range check. + env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr); + ExpectException(sioobe_); jchar chars[4] = { 'x', 'x', 'x', 'x' }; env_->GetStringRegion(s, 1, 2, &chars[1]); @@ -1529,6 +1538,9 @@ TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { ExpectException(sioobe_); env_->GetStringUTFRegion(s, 10, 1, nullptr); ExpectException(sioobe_); + // Regression test against integer overflow in range check. + env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr); + ExpectException(sioobe_); char bytes[4] = { 'x', 'x', 'x', 'x' }; env_->GetStringUTFRegion(s, 1, 2, &bytes[1]);