Skip to content

Commit 4604b04

Browse files
authored
Merge pull request #20363 from babsingh/v0.48.0-release
(0.48) Fix overflow issues
2 parents 57dac44 + 46ba2e6 commit 4604b04

File tree

7 files changed

+255
-77
lines changed

7 files changed

+255
-77
lines changed

runtime/j9vm/java11vmi.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,12 @@ JVM_DefineModule(JNIEnv * env, jobject module, jboolean isOpen, jstring version,
789789
j9array_t array = (j9array_t)J9_JNI_UNWRAP_REFERENCE(packageArray);
790790
j9object_t stringObject = J9JAVAARRAYOFOBJECT_LOAD(currentThread, array, pkgIndex);
791791
if (NULL != stringObject) {
792-
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
793-
char *packageName = (char*)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
792+
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject);
793+
char *packageName = NULL;
794+
if (utfLength < UDATA_MAX) {
795+
utfLength += 1;
796+
packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
797+
}
794798
if (NULL == packageName) {
795799
oom = TRUE;
796800
break;
@@ -992,8 +996,12 @@ JVM_AddModuleExports(JNIEnv * env, jobject fromModule, const char *package, jobj
992996
#if JAVA_SPEC_VERSION >= 15
993997
if (NULL != packageObj) {
994998
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
995-
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
996-
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
999+
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject);
1000+
char *packageName = NULL;
1001+
if (utfLength < UDATA_MAX) {
1002+
utfLength += 1;
1003+
packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1004+
}
9971005
if (NULL == packageName) {
9981006
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
9991007
goto done;
@@ -1066,8 +1074,12 @@ JVM_AddModuleExportsToAll(JNIEnv * env, jobject fromModule, const char *package)
10661074
#if JAVA_SPEC_VERSION >= 15
10671075
if (NULL != packageObj) {
10681076
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
1069-
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
1070-
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1077+
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject);
1078+
char *packageName = NULL;
1079+
if (utfLength < UDATA_MAX) {
1080+
utfLength += 1;
1081+
packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1082+
}
10711083
if (NULL == packageName) {
10721084
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
10731085
goto done;
@@ -1306,8 +1318,12 @@ JVM_AddModuleExportsToAllUnnamed(JNIEnv * env, jobject fromModule, const char *p
13061318
#if JAVA_SPEC_VERSION >= 15
13071319
if (NULL != packageObj) {
13081320
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(packageObj);
1309-
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject) + 1;
1310-
char* packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1321+
UDATA utfLength = vmFuncs->getStringUTF8Length(currentThread, stringObject);
1322+
char *packageName = NULL;
1323+
if (utfLength < UDATA_MAX) {
1324+
utfLength += 1;
1325+
packageName = (char *)j9mem_allocate_memory(utfLength, OMRMEM_CATEGORY_VM);
1326+
}
13111327
if (NULL == packageName) {
13121328
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
13131329
goto done;

runtime/jcl/common/java_lang_invoke_MethodHandleNatives.cpp

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,10 @@ getClassSignatureLength(J9VMThread *currentThread, J9Class *clazz)
410410
j9object_t sigString = J9VMJAVALANGCLASS_CLASSNAMESTRING(currentThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz));
411411
if (NULL != sigString) {
412412
/* +2 so that we can fit 'L' and ';' around the class name. */
413-
signatureLength = vm->internalVMFunctions->getStringUTF8Length(currentThread, sigString) + 2;
413+
signatureLength = vm->internalVMFunctions->getStringUTF8Length(currentThread, sigString);
414+
if (signatureLength <= (UDATA_MAX - 2)) {
415+
signatureLength += 2;
416+
}
414417
} else {
415418
J9Class *myClass = clazz;
416419
UDATA numDims = 0;
@@ -470,24 +473,27 @@ getClassSignatureInout(J9VMThread *currentThread, J9Class *clazz, LocalJ9UTF8Buf
470473
j9object_t sigString = J9VMJAVALANGCLASS_CLASSNAMESTRING(currentThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz));
471474
if (NULL != sigString) {
472475
/* +3 so that we can fit 'L' and ';' around the class name and add null-terminator. */
473-
UDATA utfLength = vm->internalVMFunctions->getStringUTF8Length(currentThread, sigString) + 3;
474-
if (utfLength <= stringBuffer->remaining()) {
475-
if (J9ROMCLASS_IS_ARRAY(clazz->romClass)) {
476-
vm->internalVMFunctions->copyStringToUTF8Helper(
477-
currentThread, sigString, J9_STR_XLAT, 0, J9VMJAVALANGSTRING_LENGTH(currentThread, sigString),
478-
stringBuffer->cursor, utfLength - 3);
479-
/* Adjust cursor to account for the call to copyStringToUTF8Helper. */
480-
stringBuffer->advanceN(utfLength - 3);
481-
} else {
482-
stringBuffer->putCharAtCursor('L');
483-
vm->internalVMFunctions->copyStringToUTF8Helper(
484-
currentThread, sigString, J9_STR_XLAT, 0, J9VMJAVALANGSTRING_LENGTH(currentThread, sigString),
485-
stringBuffer->cursor, utfLength - 3);
486-
/* Adjust cursor to account for the call to copyStringToUTF8Helper. */
487-
stringBuffer->advanceN(utfLength - 3);
488-
stringBuffer->putCharAtCursor(';');
476+
UDATA utfLength = vm->internalVMFunctions->getStringUTF8Length(currentThread, sigString);
477+
if (utfLength <= (UDATA_MAX - 3)) {
478+
utfLength += 3;
479+
if (utfLength <= stringBuffer->remaining()) {
480+
if (J9ROMCLASS_IS_ARRAY(clazz->romClass)) {
481+
vm->internalVMFunctions->copyStringToUTF8Helper(
482+
currentThread, sigString, J9_STR_XLAT, 0, J9VMJAVALANGSTRING_LENGTH(currentThread, sigString),
483+
stringBuffer->cursor, utfLength - 3);
484+
/* Adjust cursor to account for the call to copyStringToUTF8Helper. */
485+
stringBuffer->advanceN(utfLength - 3);
486+
} else {
487+
stringBuffer->putCharAtCursor('L');
488+
vm->internalVMFunctions->copyStringToUTF8Helper(
489+
currentThread, sigString, J9_STR_XLAT, 0, J9VMJAVALANGSTRING_LENGTH(currentThread, sigString),
490+
stringBuffer->cursor, utfLength - 3);
491+
/* Adjust cursor to account for the call to copyStringToUTF8Helper. */
492+
stringBuffer->advanceN(utfLength - 3);
493+
stringBuffer->putCharAtCursor(';');
494+
}
495+
result = true;
489496
}
490-
result = true;
491497
}
492498
} else {
493499
J9Class *myClass = clazz;
@@ -557,20 +563,34 @@ getJ9UTF8SignatureFromMethodTypeWithMemAlloc(J9VMThread *currentThread, j9object
557563
j9object_t ptypes = J9VMJAVALANGINVOKEMETHODTYPE_PTYPES(currentThread, typeObject);
558564
U_32 numArgs = J9INDEXABLEOBJECT_SIZE(currentThread, ptypes);
559565
UDATA signatureLength = 2; /* space for '(', ')' */
566+
UDATA tempSignatureLength = 0;
567+
UDATA signatureUtf8Size = 0;
568+
J9UTF8 *result = NULL;
569+
j9object_t rtype = NULL;
570+
J9Class *rclass = NULL;
560571
PORT_ACCESS_FROM_JAVAVM(vm);
561572

562573
/* Calculate total signature length, including all ptypes and rtype. */
563574
for (U_32 i = 0; i < numArgs; i++) {
564575
j9object_t pObject = J9JAVAARRAYOFOBJECT_LOAD(currentThread, ptypes, i);
565576
J9Class *pclass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, pObject);
566-
signatureLength += getClassSignatureLength(currentThread, pclass);
577+
tempSignatureLength = getClassSignatureLength(currentThread, pclass);
578+
if (signatureLength > (J9UTF8_MAX_LENGTH - tempSignatureLength)) {
579+
goto done;
580+
}
581+
signatureLength += tempSignatureLength;
567582
}
568-
j9object_t rtype = J9VMJAVALANGINVOKEMETHODTYPE_RTYPE(currentThread, typeObject);
569-
J9Class *rclass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, rtype);
570-
signatureLength += getClassSignatureLength(currentThread, rclass);
583+
rtype = J9VMJAVALANGINVOKEMETHODTYPE_RTYPE(currentThread, typeObject);
584+
rclass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, rtype);
585+
tempSignatureLength = getClassSignatureLength(currentThread, rclass);
586+
if (signatureLength > (J9UTF8_MAX_LENGTH - tempSignatureLength)) {
587+
goto done;
588+
}
589+
signatureLength += tempSignatureLength;
590+
591+
signatureUtf8Size = signatureLength + sizeof(J9UTF8) + 1; /* +1 for a null-terminator */
592+
result = reinterpret_cast<J9UTF8 *>(j9mem_allocate_memory(signatureUtf8Size, OMRMEM_CATEGORY_VM));
571593

572-
UDATA signatureUtf8Size = signatureLength + sizeof(J9UTF8) + 1; /* +1 for a null-terminator */
573-
J9UTF8 *result = reinterpret_cast<J9UTF8 *>(j9mem_allocate_memory(signatureUtf8Size, OMRMEM_CATEGORY_VM));
574594
if (NULL != result) {
575595
LocalJ9UTF8Buffer stringBuffer(result, signatureUtf8Size);
576596

@@ -588,6 +608,7 @@ getJ9UTF8SignatureFromMethodTypeWithMemAlloc(J9VMThread *currentThread, j9object
588608
stringBuffer.commitLength();
589609
}
590610

611+
done:
591612
return result;
592613
}
593614

@@ -1036,12 +1057,21 @@ Java_java_lang_invoke_MethodHandleNatives_resolve(
10361057
} else {
10371058
LocalJ9UTF8Buffer stringBuffer(reinterpret_cast<J9UTF8 *>(signatureBuffer), sizeof(signatureBuffer));
10381059
signature = getJ9UTF8SignatureFromMethodType(currentThread, typeObject, &stringBuffer);
1060+
if (NULL == signature) {
1061+
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGINTERNALERROR, NULL);
1062+
goto done;
1063+
}
10391064
}
10401065
} else if (J9VMJAVALANGSTRING_OR_NULL(vm) == typeClass) {
10411066
signature = vmFuncs->copyStringToJ9UTF8WithMemAlloc(currentThread, typeObject, J9_STR_XLAT, "", 0, signatureBuffer, sizeof(signatureBuffer));
10421067
} else if (J9VMJAVALANGCLASS(vm) == typeClass) {
10431068
J9Class *rclass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, typeObject);
1044-
UDATA signatureLength = getClassSignatureLength(currentThread, rclass) + sizeof(J9UTF8) + 1 /* null-terminator */;
1069+
UDATA signatureLength = getClassSignatureLength(currentThread, rclass);
1070+
if (signatureLength > J9UTF8_MAX_LENGTH) {
1071+
vmFuncs->setCurrentExceptionUTF(currentThread, J9VMCONSTANTPOOL_JAVALANGINTERNALERROR, NULL);
1072+
goto done;
1073+
}
1074+
signatureLength += sizeof(J9UTF8) + 1 /* null-terminator */;
10451075
LocalJ9UTF8Buffer stringBuffer;
10461076
if (signatureLength <= sizeof(signatureBuffer)) {
10471077
stringBuffer = LocalJ9UTF8Buffer(reinterpret_cast<J9UTF8 *>(signatureBuffer), sizeof(signatureBuffer));

runtime/oti/j9nonbuilder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3587,6 +3587,8 @@ typedef struct J9UTF8 {
35873587
#pragma warning(pop)
35883588
#endif /* defined(_MSC_VER) */
35893589

3590+
#define J9UTF8_MAX_LENGTH U_16_MAX
3591+
35903592
typedef struct J9ROMClass {
35913593
U_32 romSize;
35923594
U_32 singleScalarStaticCount;
@@ -4803,7 +4805,8 @@ typedef struct J9InternalVMFunctions {
48034805
struct J9Class* ( *internalFindKnownClass)(struct J9VMThread *currentThread, UDATA index, UDATA flags) ;
48044806
struct J9Class* ( *resolveKnownClass)(struct J9JavaVM * vm, UDATA index) ;
48054807
UDATA ( *computeHashForUTF8)(const U_8 * string, UDATA size) ;
4806-
IDATA ( *getStringUTF8Length)(struct J9VMThread *vmThread, j9object_t string) ;
4808+
UDATA ( *getStringUTF8Length)(struct J9VMThread *vmThread, j9object_t string) ;
4809+
U_64 ( *getStringUTF8LengthTruncated)(struct J9VMThread *vmThread, j9object_t string, U_64 maxLength) ;
48074810
void ( *acquireExclusiveVMAccess)(struct J9VMThread * vmThread) ;
48084811
void ( *releaseExclusiveVMAccess)(struct J9VMThread * vmThread) ;
48094812
void ( *internalReleaseVMAccess)(struct J9VMThread * currentThread) ;

runtime/oti/vm_api.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,13 +3580,30 @@ copyStringToUTF8Helper(J9VMThread *vmThread, j9object_t string, UDATA stringFlag
35803580

35813581

35823582
/**
3583-
* @brief
3584-
* @param *vm
3585-
* @param *string
3586-
* @return IDATA
3587-
*/
3588-
IDATA
3589-
getStringUTF8Length(J9VMThread *vmThread,j9object_t string);
3583+
* @brief Find the length of the string object when it is converted to UTF-8.
3584+
*
3585+
* Note: On 32-bit platforms, the length may be truncated.
3586+
*
3587+
* @param vm a pointer to J9JavaVM
3588+
* @param string a string object
3589+
*
3590+
* @return the length of the string in UTF-8
3591+
*/
3592+
UDATA
3593+
getStringUTF8Length(J9VMThread *vmThread, j9object_t string);
3594+
3595+
/**
3596+
* @brief Find the length of the string object when it is converted to UTF-8, but truncate it
3597+
* using maxLength as the upper bound.
3598+
*
3599+
* @param vm a pointer to J9JavaVM
3600+
* @param string a string object
3601+
* @param maxLength the upper bound of the length used for truncation
3602+
*
3603+
* @return the length of the string in UTF-8
3604+
*/
3605+
U_64
3606+
getStringUTF8LengthTruncated(J9VMThread *vmThread, j9object_t string, U_64 maxLength);
35903607

35913608

35923609
/**

runtime/vm/intfunc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ J9InternalVMFunctions J9InternalFunctions = {
7575
resolveKnownClass,
7676
computeHashForUTF8,
7777
getStringUTF8Length,
78+
getStringUTF8LengthTruncated,
7879
acquireExclusiveVMAccess,
7980
releaseExclusiveVMAccess,
8081
internalReleaseVMAccess,

runtime/vm/jnimisc.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ getStringUTFLength(JNIEnv *env, jstring string)
827827
VM_VMAccess::inlineEnterVMFromJNI(currentThread);
828828
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(string);
829829

830-
UDATA utfLength = getStringUTF8Length(currentThread, stringObject);
830+
U_64 utfLength = getStringUTF8LengthTruncated(currentThread, stringObject, INT32_MAX);
831831
VM_VMAccess::inlineExitVMToJNI(currentThread);
832832
return (jsize)utfLength;
833833
}
@@ -838,14 +838,17 @@ getStringUTFCharsImpl(JNIEnv *env, jstring string, jboolean *isCopy, jboolean en
838838
J9VMThread *currentThread = (J9VMThread*)env;
839839
VM_VMAccess::inlineEnterVMFromJNI(currentThread);
840840
j9object_t stringObject = J9_JNI_UNWRAP_REFERENCE(string);
841-
/* Add 1 for null terminator */
842-
UDATA utfLength = getStringUTF8Length(currentThread, stringObject) + 1;
843841

842+
UDATA utfLength = getStringUTF8Length(currentThread, stringObject);
844843
U_8 *utfChars = NULL;
845-
if (ensureMem32) {
846-
utfChars = (U_8*)jniArrayAllocateMemory32FromThread(currentThread, utfLength);
847-
} else {
848-
utfChars = (U_8*)jniArrayAllocateMemoryFromThread(currentThread, utfLength);
844+
if (utfLength < UDATA_MAX) {
845+
/* Add 1 for a null terminator. */
846+
utfLength += 1;
847+
if (ensureMem32) {
848+
utfChars = (U_8 *)jniArrayAllocateMemory32FromThread(currentThread, utfLength);
849+
} else {
850+
utfChars = (U_8 *)jniArrayAllocateMemoryFromThread(currentThread, utfLength);
851+
}
849852
}
850853

851854
if (NULL == utfChars) {

0 commit comments

Comments
 (0)