Skip to content

Commit c70741a

Browse files
authored
Merge pull request #19898 from theresa-m/maxclassname_46
0.46: Enforce maximum name size during class loading
2 parents 6c99fa9 + b36ebeb commit c70741a

File tree

5 files changed

+76
-2
lines changed

5 files changed

+76
-2
lines changed

runtime/j9vm/j7vmi.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2566,14 +2566,32 @@ jvmDefineClassHelper(JNIEnv *env, jobject classLoaderObject,
25662566

25672567
if (NULL != className) {
25682568
j9object_t classNameObject = J9_JNI_UNWRAP_REFERENCE(className);
2569+
2570+
/* Perform maximum length check to avoid copy in extreme cases. */
2571+
if (J9VMJAVALANGSTRING_LENGTH(currentThread, classNameObject) > J9VM_MAX_CLASS_NAME_LENGTH) {
2572+
vmFuncs->setCurrentExceptionNLS(currentThread,
2573+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
2574+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
2575+
goto done;
2576+
}
2577+
25692578
utf8Name = (U_8*)vmFuncs->copyStringToUTF8WithMemAlloc(currentThread, classNameObject, J9_STR_NULL_TERMINATE_RESULT, "", 0, utf8NameStackBuffer, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);
25702579
if (NULL == utf8Name) {
25712580
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
25722581
goto done;
25732582
}
25742583

2584+
if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
2585+
vmFuncs->setCurrentExceptionNLS(currentThread,
2586+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
2587+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
2588+
goto done;
2589+
}
2590+
25752591
if (CLASSNAME_INVALID == vmFuncs->verifyQualifiedName(currentThread, utf8Name, utf8Length, CLASSNAME_VALID_NON_ARRARY)) {
2576-
vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR, (UDATA *)*(j9object_t*)className);
2592+
vmFuncs->setCurrentException(currentThread,
2593+
J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR,
2594+
(UDATA *)*(j9object_t *)className);
25772595
goto done;
25782596
}
25792597
}

runtime/jcl/common/jcldefine.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "jclprots.h"
2626
#include "j9protos.h"
2727
#include "j9jclnls.h"
28+
#include "j9vmnls.h"
2829

2930
jclass
3031
defineClassCommon(JNIEnv *env, jobject classLoaderObject,
@@ -100,13 +101,28 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject,
100101
stringFlags |= J9_STR_XLAT;
101102
}
102103

104+
/* Perform maximum length check to avoid copy in extreme cases. */
105+
if (J9VMJAVALANGSTRING_LENGTH(currentThread, classNameObject) > J9VM_MAX_CLASS_NAME_LENGTH) {
106+
vmFuncs->setCurrentExceptionNLS(currentThread,
107+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
108+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
109+
goto done;
110+
}
111+
103112
utf8Name = (U_8*)vmFuncs->copyStringToUTF8WithMemAlloc(currentThread, classNameObject, stringFlags, "", 0, utf8NameStackBuffer, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);
104113

105114
if (NULL == utf8Name) {
106115
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
107116
goto done;
108117
}
109118

119+
if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
120+
vmFuncs->setCurrentExceptionNLS(currentThread,
121+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
122+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
123+
goto done;
124+
}
125+
110126
if (validateName && (CLASSNAME_INVALID == vmFuncs->verifyQualifiedName(currentThread, utf8Name, utf8Length, CLASSNAME_VALID_NON_ARRARY))) {
111127
/* We don't yet know if the class being defined is exempt. Setting this option tells
112128
* defineClassCommon() to fail if it discovers that the class is not exempt. That failure

runtime/nls/j9vm/j9vm.nls

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,3 +2401,25 @@ J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.explanation=checkTran
24012401
J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.system_action=The JVM will throw a JVMRestoreException.
24022402
J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.user_response=View CRIU documentation to determine how to resolve the error.
24032403
# END NON-TRANSLATABLE
2404+
2405+
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE=Value specified to --sun-misc-unsafe-memory-access not recognized: '%s'
2406+
# START NON-TRANSLATABLE
2407+
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.sample_input_1=disallow
2408+
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.explanation=The value specified is not known.
2409+
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.system_action=The JVM will fail to start.
2410+
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.user_response=Change the value to one of "allow", "warn", "debug" or "deny".
2411+
# END NON-TRANSLATABLE
2412+
2413+
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND=Either the %s environment variable is not set, or the file does not exist in the specified location.
2414+
# START NON-TRANSLATABLE
2415+
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.explanation=Couldn't find JFR metadata blob file.
2416+
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.system_action=The JVM will not generate a JFR file.
2417+
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.user_response=Set the required environment variables.
2418+
# END NON-TRANSLATABLE
2419+
2420+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH=Class name exceeds maximum length
2421+
# START NON-TRANSLATABLE
2422+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.explanation=Class name cannot be longer than 65535 characters.
2423+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.system_action=The JVM will throw a ClassNotFoundException.
2424+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.user_response=Shorten the class name.
2425+
# END NON-TRANSLATABLE

runtime/oti/j9nonbuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
#include "j9javaaccessflags.h"
3737

3838
#define J9VM_MAX_HIDDEN_FIELDS_PER_CLASS 8
39+
/* Class names are stored in the VM as CONSTANT_Utf8_info which stores
40+
* length in two bytes.
41+
*/
42+
#define J9VM_MAX_CLASS_NAME_LENGTH 0xFFFF
3943

4044
#define J9VM_DLT_HISTORY_SIZE 16
4145
#define J9VM_OBJECT_MONITOR_CACHE_SIZE 32

runtime/vm/classsupport.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,14 @@ internalFindClassString(J9VMThread* currentThread, j9object_t moduleName, j9obje
316316
stringFlags |= J9_STR_XLAT;
317317
}
318318

319+
/* Perform maximum length check to avoid copy in extreme cases. */
320+
if (J9VMJAVALANGSTRING_LENGTH(currentThread, className) > J9VM_MAX_CLASS_NAME_LENGTH) {
321+
setCurrentExceptionNLS(currentThread,
322+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
323+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
324+
return NULL;
325+
}
326+
319327
utf8Name = (U_8*)copyStringToUTF8WithMemAlloc(currentThread, className, stringFlags, "", 0, (char *)localBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);
320328
if (NULL == utf8Name) {
321329
/* Throw out-of-memory */
@@ -324,7 +332,13 @@ internalFindClassString(J9VMThread* currentThread, j9object_t moduleName, j9obje
324332
}
325333

326334
/* Make sure the name is legal */
327-
if ((CLASSNAME_INVALID == allowedBitsForClassName)
335+
if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
336+
if (CLASSNAME_INVALID != allowedBitsForClassName) {
337+
setCurrentExceptionNLS(currentThread,
338+
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
339+
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
340+
}
341+
} else if ((CLASSNAME_INVALID == allowedBitsForClassName)
328342
|| (CLASSNAME_INVALID != verifyQualifiedName(currentThread, utf8Name, utf8Length, allowedBitsForClassName))
329343
) {
330344
if (NULL != moduleName) {

0 commit comments

Comments
 (0)