Skip to content

Commit

Permalink
Merge pull request #10956 from mikezhang1234567890/v0.23.0-release
Browse files Browse the repository at this point in the history
(v.0.23) Disallow MUE in class file UTF8
  • Loading branch information
pshipton authored Oct 21, 2020
2 parents 4c0da55 + e473dae commit 0394ef7
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 15 deletions.
26 changes: 24 additions & 2 deletions runtime/bcutil/bcutil.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2019 IBM Corp. and others
* Copyright (c) 1991, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -222,17 +222,27 @@ bcutil_J9VMDllMain(J9JavaVM* vm, IDATA stage, void* reserved)
This function ignores surrogates and treats them as two separate three byte
encodings. This is valid.
The bit CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM is set in mueAsciiStatus if a
non-null UTF character is extended using modified UTF-8 (MUE)format,
similar to the null character. For classfile versions 48 and up, the JVM is
supposed to reject MUE characters.
The bit CFR_FOUND_SEPARATOR_IN_MUE_FORM is set in mueAsciiStatus if the
character '/' was found in MUE form, which is specifically
disallowed in class names even for classfile version 47 and lower.
If mueAsciiStatus is left NULL it is not used.
Returns compressed length or -1.
*/

I_32
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length)
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length, U_8 *mueAsciiStatus)
{
U_8 *originalDest = dest;
U_8 *originalSource = source;
U_8 *sourceEnd = source + length;
UDATA firstByte, nextByte, outWord, charLength, compression = 0;
I_32 result = -1;
U_8 mueStatus = 0;

Trc_BCU_verifyCanonisizeAndCopyUTF8_Entry(dest, source, length);

Expand Down Expand Up @@ -291,6 +301,10 @@ j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length)

/* Overwrite the multibyte UTF8 character only if shorter */
if ((outWord != 0) && (outWord < 0x80)) {
/* character '/' handled specially in class name utf8 */
if ((UDATA)'/' == outWord) {
mueStatus |= CFR_FOUND_SEPARATOR_IN_MUE_FORM;
}
/* One byte must be shorter in here */
dest = originalDest + (source - originalSource - charLength - compression);
*dest++ = (U_8) outWord;
Expand All @@ -306,8 +320,16 @@ j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length)
}
}

if (compression > 0) {
mueStatus |= CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM;
}

result = (I_32) (length - compression);

if (NULL != mueAsciiStatus) {
*mueAsciiStatus = mueStatus;
}

fail:
Trc_BCU_verifyCanonisizeAndCopyUTF8_Exit(result);

Expand Down
30 changes: 20 additions & 10 deletions runtime/bcutil/cfreader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,9 +1228,11 @@ readPool(J9CfrClassFile* classfile, U_8* data, U_8* dataEnd, U_8* segment, U_8*
return -2;
}
CHECK_EOF(size);
verifyResult = j9bcutil_verifyCanonisizeAndCopyUTF8(info->bytes, index, size);
verifyResult = j9bcutil_verifyCanonisizeAndCopyUTF8(info->bytes, index, size, &(info->flags1));
info->slot1 = (U_32) verifyResult;
if (verifyResult < 0) {
if ((verifyResult < 0) ||
(J9_ARE_ALL_BITS_SET(info->flags1, CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM) && (classfile->majorVersion >= 48))
) {
errorCode = J9NLS_CFR_ERR_BAD_UTF8__ID;
offset = (U_32) (index - data - 1);
goto _errorFound;
Expand Down Expand Up @@ -2587,7 +2589,7 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
goto _errorFound;
}

if((value & CFR_ACC_FINAL)&&(value & CFR_ACC_ABSTRACT)) {
if ((value & CFR_ACC_FINAL)&&(value & CFR_ACC_ABSTRACT)) {
errorCode = J9NLS_CFR_ERR_FINAL_ABSTRACT_CLASS__ID;
offset = endOfConstantPool;
goto _errorFound;
Expand All @@ -2602,39 +2604,47 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
}

value = classfile->thisClass;
if((!value)||(value >= classfile->constantPoolCount)) {
if ((!value)||(value >= classfile->constantPoolCount)) {
errorCode = J9NLS_CFR_ERR_BAD_INDEX__ID;
offset = endOfConstantPool + 2;
goto _errorFound;
}

if((classfile->constantPool)&&(classfile->constantPool[value].tag != CFR_CONSTANT_Class)) {
if ((classfile->constantPool) && (classfile->constantPool[value].tag != CFR_CONSTANT_Class)) {
errorCode = J9NLS_CFR_ERR_NOT_CLASS__ID;
offset = endOfConstantPool + 2;
goto _errorFound;
}
if ((classfile->constantPool) && (CFR_CONSTANT_Class == classfile->constantPool[value].tag)) {
value = classfile->constantPool[classfile->thisClass].slot1;
if (J9_ARE_ALL_BITS_SET(classfile->constantPool[value].flags1, CFR_FOUND_SEPARATOR_IN_MUE_FORM) && (classfile->majorVersion < 48)) {
errorCode = J9NLS_CFR_ERR_BAD_CLASS_NAME__ID;
offset = endOfConstantPool + 2;
goto _errorFound;
}
}

value = classfile->superClass;
if(value >= classfile->constantPoolCount) {
if (value >= classfile->constantPoolCount) {
errorCode = J9NLS_CFR_ERR_BAD_INDEX__ID;
offset = endOfConstantPool + 4;
goto _errorFound;
}

if(value == 0) {
if (0 == value) {
/* Check against j.l.O. */
if(!utf8Equal(&classfile->constantPool[classfile->constantPool[classfile->thisClass].slot1], "java/lang/Object", 16)) {
errorCode = J9NLS_CFR_ERR_NULL_SUPER__ID;
offset = endOfConstantPool + 4;
goto _errorFound;
}
} else if(classfile->constantPool[value].tag != CFR_CONSTANT_Class) {
} else if (classfile->constantPool[value].tag != CFR_CONSTANT_Class) {
errorCode = J9NLS_CFR_ERR_SUPER_NOT_CLASS__ID;
offset = endOfConstantPool + 4;
goto _errorFound;
}

for(i = 0; i < classfile->interfacesCount; i++) {
for (i = 0; i < classfile->interfacesCount; i++) {
U_32 j;
J9CfrConstantPoolInfo* cpInfo;
value = classfile->interfaces[i];
Expand Down Expand Up @@ -2662,7 +2672,7 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
}

/* Check that interfaces subclass object. */
if(classfile->accessFlags & CFR_ACC_INTERFACE) {
if (classfile->accessFlags & CFR_ACC_INTERFACE) {
/* Check against j.l.O. */
if(!utf8Equal(&classfile->constantPool[classfile->constantPool[classfile->superClass].slot1], "java/lang/Object", 16)) {
errorCode = J9NLS_CFR_ERR_INTERFACE_SUPER_NOT_OBJECT__ID;
Expand Down
4 changes: 2 additions & 2 deletions runtime/bcutil/test/natives/bcunatives.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2014 IBM Corp. and others
* Copyright (c) 2001, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -55,7 +55,7 @@ Java_com_ibm_j9_test_bcutil_TestNatives_verifyCanonisizeAndCopyUTF8(JNIEnv *env,
src[i] = (char) jSrc[i];
}

result = j9bcutil_verifyCanonisizeAndCopyUTF8(dest, src, length);
result = j9bcutil_verifyCanonisizeAndCopyUTF8(dest, src, length, NULL);

for (i =0; i < length; i++) {
jDest[i] = dest[i];
Expand Down
3 changes: 2 additions & 1 deletion runtime/oti/bcutil_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ j9bcutil_freeTranslationBuffers (J9PortLibrary * portLib, J9TranslationBufferSet
* @param *dest
* @param *source
* @param length
* @param mueAsciiStatus If any non-null ASCII characters are represented in modified UTF-8 2 byte format instead of in 1 byte
* @return I_32
*/
I_32
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length);
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length, U_8 *mueAsciiStatus);


/**
Expand Down
3 changes: 3 additions & 0 deletions runtime/oti/cfr.h
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,9 @@ typedef struct J9CfrClassFile {

#define ANON_CLASSNAME_CHARACTER_SEPARATOR '/'

#define CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM 0x1
#define CFR_FOUND_SEPARATOR_IN_MUE_FORM 0x2

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 0394ef7

Please sign in to comment.