diff options
author | Brian Carlstrom <bdc@google.com> | 2014-06-24 23:36:28 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2014-06-25 01:44:33 -0700 |
commit | 45d26c86b00580593067ca42091ad66cf7dc4f7c (patch) | |
tree | b5fa7e7df42c1f7e7efb21b085980faac0e67937 | |
parent | b5dc9444777bb027b070d3ff3fcf7a2a3fb7e3dc (diff) | |
download | android_art-45d26c86b00580593067ca42091ad66cf7dc4f7c.tar.gz android_art-45d26c86b00580593067ca42091ad66cf7dc4f7c.tar.bz2 android_art-45d26c86b00580593067ca42091ad66cf7dc4f7c.zip |
Treat larger than jint capacity in NewDirectByteBuffer as an error
Bug: 15854028
Change-Id: If78921f4ba2b38a9d0bb421acf9c8bca962ed42a
-rw-r--r-- | runtime/check_jni.cc | 4 | ||||
-rw-r--r-- | runtime/jni_internal.cc | 9 | ||||
-rw-r--r-- | runtime/jni_internal_test.cc | 7 |
3 files changed, 14 insertions, 6 deletions
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc index a81648958b..fefb907422 100644 --- a/runtime/check_jni.cc +++ b/runtime/check_jni.cc @@ -1757,9 +1757,7 @@ PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D'); CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity); if (address == nullptr) { JniAbortF(__FUNCTION__, "non-nullable address is NULL"); - } - if (capacity < 0) { - JniAbortF(__FUNCTION__, "capacity must be non-negative: %" PRId64, capacity); + return nullptr; } return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity)); } diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 513b4092de..2fadfb0f6a 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -2447,13 +2447,18 @@ class JNI { static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { if (capacity < 0) { JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity); + return nullptr; } if (address == nullptr && capacity != 0) { JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity); + return nullptr; } - // At the moment, the capacity is limited to 32 bits. - CHECK_LE(capacity, 0xffffffff); + // At the moment, the capacity is limited to a jint (31 bits). + if (capacity > INT_MAX) { + JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity); + return nullptr; + } jlong address_arg = reinterpret_cast<jlong>(address); jint capacity_arg = static_cast<jint>(capacity); diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc index 5e46c57de1..218ae95266 100644 --- a/runtime/jni_internal_test.cc +++ b/runtime/jni_internal_test.cc @@ -1515,6 +1515,12 @@ TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCa ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class)); ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes); ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes))); + + { + CheckJniAbortCatcher check_jni_abort_catcher; + env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) * 2); + check_jni_abort_catcher.Check("in call to NewDirectByteBuffer"); + } } TEST_F(JniInternalTest, MonitorEnterExit) { @@ -1568,7 +1574,6 @@ TEST_F(JniInternalTest, MonitorEnterExit) { CheckJniAbortCatcher check_jni_abort_catcher; env_->MonitorEnter(nullptr); check_jni_abort_catcher.Check("in call to MonitorEnter"); - env_->MonitorExit(nullptr); check_jni_abort_catcher.Check("in call to MonitorExit"); } |