Skip to content

Commit

Permalink
Merge pull request #19898 from theresa-m/maxclassname_46
Browse files Browse the repository at this point in the history
0.46: Enforce maximum name size during class loading
  • Loading branch information
keithc-ca authored Jul 23, 2024
2 parents 6c99fa9 + b36ebeb commit c70741a
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
20 changes: 19 additions & 1 deletion runtime/j9vm/j7vmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2566,14 +2566,32 @@ jvmDefineClassHelper(JNIEnv *env, jobject classLoaderObject,

if (NULL != className) {
j9object_t classNameObject = J9_JNI_UNWRAP_REFERENCE(className);

/* Perform maximum length check to avoid copy in extreme cases. */
if (J9VMJAVALANGSTRING_LENGTH(currentThread, classNameObject) > J9VM_MAX_CLASS_NAME_LENGTH) {
vmFuncs->setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
goto done;
}

utf8Name = (U_8*)vmFuncs->copyStringToUTF8WithMemAlloc(currentThread, classNameObject, J9_STR_NULL_TERMINATE_RESULT, "", 0, utf8NameStackBuffer, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);
if (NULL == utf8Name) {
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
goto done;
}

if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
vmFuncs->setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
goto done;
}

if (CLASSNAME_INVALID == vmFuncs->verifyQualifiedName(currentThread, utf8Name, utf8Length, CLASSNAME_VALID_NON_ARRARY)) {
vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR, (UDATA *)*(j9object_t*)className);
vmFuncs->setCurrentException(currentThread,
J9VMCONSTANTPOOL_JAVALANGNOCLASSDEFFOUNDERROR,
(UDATA *)*(j9object_t *)className);
goto done;
}
}
Expand Down
16 changes: 16 additions & 0 deletions runtime/jcl/common/jcldefine.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "jclprots.h"
#include "j9protos.h"
#include "j9jclnls.h"
#include "j9vmnls.h"

jclass
defineClassCommon(JNIEnv *env, jobject classLoaderObject,
Expand Down Expand Up @@ -100,13 +101,28 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject,
stringFlags |= J9_STR_XLAT;
}

/* Perform maximum length check to avoid copy in extreme cases. */
if (J9VMJAVALANGSTRING_LENGTH(currentThread, classNameObject) > J9VM_MAX_CLASS_NAME_LENGTH) {
vmFuncs->setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
goto done;
}

utf8Name = (U_8*)vmFuncs->copyStringToUTF8WithMemAlloc(currentThread, classNameObject, stringFlags, "", 0, utf8NameStackBuffer, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);

if (NULL == utf8Name) {
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
goto done;
}

if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
vmFuncs->setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
goto done;
}

if (validateName && (CLASSNAME_INVALID == vmFuncs->verifyQualifiedName(currentThread, utf8Name, utf8Length, CLASSNAME_VALID_NON_ARRARY))) {
/* We don't yet know if the class being defined is exempt. Setting this option tells
* defineClassCommon() to fail if it discovers that the class is not exempt. That failure
Expand Down
22 changes: 22 additions & 0 deletions runtime/nls/j9vm/j9vm.nls
Original file line number Diff line number Diff line change
Expand Up @@ -2401,3 +2401,25 @@ J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.explanation=checkTran
J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.system_action=The JVM will throw a JVMRestoreException.
J9NLS_VM_CRIU_CHECK_TRANSITION_TO_DEBUG_INTERPRETER_FAILED.user_response=View CRIU documentation to determine how to resolve the error.
# END NON-TRANSLATABLE

J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE=Value specified to --sun-misc-unsafe-memory-access not recognized: '%s'
# START NON-TRANSLATABLE
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.sample_input_1=disallow
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.explanation=The value specified is not known.
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.system_action=The JVM will fail to start.
J9NLS_VM_UNRECOGNISED_SUN_MISC_UNSAFE_MEMORY_ACCESS_VALUE.user_response=Change the value to one of "allow", "warn", "debug" or "deny".
# END NON-TRANSLATABLE

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.
# START NON-TRANSLATABLE
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.explanation=Couldn't find JFR metadata blob file.
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.system_action=The JVM will not generate a JFR file.
J9NLS_VM_OPENJ9_JFR_METADATA_FILE_NOT_FOUND.user_response=Set the required environment variables.
# END NON-TRANSLATABLE

J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH=Class name exceeds maximum length
# START NON-TRANSLATABLE
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.explanation=Class name cannot be longer than 65535 characters.
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.system_action=The JVM will throw a ClassNotFoundException.
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH.user_response=Shorten the class name.
# END NON-TRANSLATABLE
4 changes: 4 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
#include "j9javaaccessflags.h"

#define J9VM_MAX_HIDDEN_FIELDS_PER_CLASS 8
/* Class names are stored in the VM as CONSTANT_Utf8_info which stores
* length in two bytes.
*/
#define J9VM_MAX_CLASS_NAME_LENGTH 0xFFFF

#define J9VM_DLT_HISTORY_SIZE 16
#define J9VM_OBJECT_MONITOR_CACHE_SIZE 32
Expand Down
16 changes: 15 additions & 1 deletion runtime/vm/classsupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,14 @@ internalFindClassString(J9VMThread* currentThread, j9object_t moduleName, j9obje
stringFlags |= J9_STR_XLAT;
}

/* Perform maximum length check to avoid copy in extreme cases. */
if (J9VMJAVALANGSTRING_LENGTH(currentThread, className) > J9VM_MAX_CLASS_NAME_LENGTH) {
setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
return NULL;
}

utf8Name = (U_8*)copyStringToUTF8WithMemAlloc(currentThread, className, stringFlags, "", 0, (char *)localBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, &utf8Length);
if (NULL == utf8Name) {
/* Throw out-of-memory */
Expand All @@ -324,7 +332,13 @@ internalFindClassString(J9VMThread* currentThread, j9object_t moduleName, j9obje
}

/* Make sure the name is legal */
if ((CLASSNAME_INVALID == allowedBitsForClassName)
if (utf8Length > J9VM_MAX_CLASS_NAME_LENGTH) {
if (CLASSNAME_INVALID != allowedBitsForClassName) {
setCurrentExceptionNLS(currentThread,
J9VMCONSTANTPOOL_JAVALANGCLASSNOTFOUNDEXCEPTION,
J9NLS_VM_CLASS_NAME_EXCEEDS_MAX_LENGTH);
}
} else if ((CLASSNAME_INVALID == allowedBitsForClassName)
|| (CLASSNAME_INVALID != verifyQualifiedName(currentThread, utf8Name, utf8Length, allowedBitsForClassName))
) {
if (NULL != moduleName) {
Expand Down

0 comments on commit c70741a

Please sign in to comment.