src/share/vm/prims/jniCheck.cpp
Print this page
rev 1876 : 6539281 -Xcheck:jni should validate char* argument to ReleaseStringUTFChars
*** 1286,1321 ****
jsize result = UNCHECKED()->GetStringLength(env,str);
functionExit(env);
return result;
JNI_END
JNI_ENTRY_CHECKED(const jchar *,
checked_jni_GetStringChars(JNIEnv *env,
jstring str,
jboolean *isCopy))
functionEnter(thr);
IN_VM(
checkString(thr, str);
)
const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
functionExit(env);
! return result;
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ReleaseStringChars(JNIEnv *env,
jstring str,
const jchar *chars))
functionEnterExceptionAllowed(thr);
IN_VM(
checkString(thr, str);
)
! /* cannot check validity of copy, unless every request is logged by
! * checking code. Implementation of this check is deferred until a
! * subsequent release.
! */
! UNCHECKED()->ReleaseStringChars(env,str,chars);
functionExit(env);
JNI_END
JNI_ENTRY_CHECKED(jstring,
checked_jni_NewStringUTF(JNIEnv *env,
--- 1286,1333 ----
jsize result = UNCHECKED()->GetStringLength(env,str);
functionExit(env);
return result;
JNI_END
+ // Arbitrary (but well-known) tag
+ #define STRING_TAG 0x47114711
+
JNI_ENTRY_CHECKED(const jchar *,
checked_jni_GetStringChars(JNIEnv *env,
jstring str,
jboolean *isCopy))
functionEnter(thr);
IN_VM(
checkString(thr, str);
)
const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
+
+ size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
+ jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), "checked_jni_GetStringChars");
+ *tagLocation = STRING_TAG;
+ jchar* newResult = (jchar*) (tagLocation + 1);
+ memcpy(newResult, result, len * sizeof(jchar));
+ // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
+ FreeHeap((char*)result);
+
functionExit(env);
! return newResult;
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ReleaseStringChars(JNIEnv *env,
jstring str,
const jchar *chars))
functionEnterExceptionAllowed(thr);
IN_VM(
checkString(thr, str);
)
! jint *tagLocation = ((jint*) chars) - 1;
! if (*tagLocation != STRING_TAG) {
! NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
! }
! UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation);
functionExit(env);
JNI_END
JNI_ENTRY_CHECKED(jstring,
checked_jni_NewStringUTF(JNIEnv *env,
*** 1336,1371 ****
jsize result = UNCHECKED()->GetStringUTFLength(env,str);
functionExit(env);
return result;
JNI_END
JNI_ENTRY_CHECKED(const char *,
checked_jni_GetStringUTFChars(JNIEnv *env,
jstring str,
jboolean *isCopy))
functionEnter(thr);
IN_VM(
checkString(thr, str);
)
const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
functionExit(env);
! return result;
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ReleaseStringUTFChars(JNIEnv *env,
jstring str,
const char* chars))
functionEnterExceptionAllowed(thr);
IN_VM(
checkString(thr, str);
)
! /* cannot check validity of copy, unless every request is logged by
! * checking code. Implementation of this check is deferred until a
! * subsequent release.
! */
! UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
functionExit(env);
JNI_END
JNI_ENTRY_CHECKED(jsize,
checked_jni_GetArrayLength(JNIEnv *env,
--- 1348,1395 ----
jsize result = UNCHECKED()->GetStringUTFLength(env,str);
functionExit(env);
return result;
JNI_END
+ // Arbitrary (but well-known) tag - different than GetStringChars
+ #define STRING_UTF_TAG 0x48124812
+
JNI_ENTRY_CHECKED(const char *,
checked_jni_GetStringUTFChars(JNIEnv *env,
jstring str,
jboolean *isCopy))
functionEnter(thr);
IN_VM(
checkString(thr, str);
)
const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
+
+ size_t len = strlen(result) + 1; // + 1 for NULL termination
+ jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), "checked_jni_GetStringUTFChars");
+ *tagLocation = STRING_UTF_TAG;
+ char* newResult = (char*) (tagLocation + 1);
+ strcpy(newResult, result);
+ // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
+ FreeHeap((char*)result);
+
functionExit(env);
! return newResult;
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ReleaseStringUTFChars(JNIEnv *env,
jstring str,
const char* chars))
functionEnterExceptionAllowed(thr);
IN_VM(
checkString(thr, str);
)
! jint* tagLocation = ((jint*) chars) - 1;
! if (*tagLocation != STRING_UTF_TAG) {
! NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
! }
! UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation);
functionExit(env);
JNI_END
JNI_ENTRY_CHECKED(jsize,
checked_jni_GetArrayLength(JNIEnv *env,