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,