Skip to content

Commit 0394ef7

Browse files
authored
Merge pull request #10956 from mikezhang1234567890/v0.23.0-release
(v.0.23) Disallow MUE in class file UTF8
2 parents 4c0da55 + e473dae commit 0394ef7

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

runtime/bcutil/bcutil.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 1991, 2019 IBM Corp. and others
2+
* Copyright (c) 1991, 2020 IBM Corp. and others
33
*
44
* This program and the accompanying materials are made available under
55
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -222,17 +222,27 @@ bcutil_J9VMDllMain(J9JavaVM* vm, IDATA stage, void* reserved)
222222
This function ignores surrogates and treats them as two separate three byte
223223
encodings. This is valid.
224224
225+
The bit CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM is set in mueAsciiStatus if a
226+
non-null UTF character is extended using modified UTF-8 (MUE)format,
227+
similar to the null character. For classfile versions 48 and up, the JVM is
228+
supposed to reject MUE characters.
229+
The bit CFR_FOUND_SEPARATOR_IN_MUE_FORM is set in mueAsciiStatus if the
230+
character '/' was found in MUE form, which is specifically
231+
disallowed in class names even for classfile version 47 and lower.
232+
If mueAsciiStatus is left NULL it is not used.
233+
225234
Returns compressed length or -1.
226235
*/
227236

228237
I_32
229-
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length)
238+
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length, U_8 *mueAsciiStatus)
230239
{
231240
U_8 *originalDest = dest;
232241
U_8 *originalSource = source;
233242
U_8 *sourceEnd = source + length;
234243
UDATA firstByte, nextByte, outWord, charLength, compression = 0;
235244
I_32 result = -1;
245+
U_8 mueStatus = 0;
236246

237247
Trc_BCU_verifyCanonisizeAndCopyUTF8_Entry(dest, source, length);
238248

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

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

323+
if (compression > 0) {
324+
mueStatus |= CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM;
325+
}
326+
309327
result = (I_32) (length - compression);
310328

329+
if (NULL != mueAsciiStatus) {
330+
*mueAsciiStatus = mueStatus;
331+
}
332+
311333
fail:
312334
Trc_BCU_verifyCanonisizeAndCopyUTF8_Exit(result);
313335

runtime/bcutil/cfreader.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,9 +1228,11 @@ readPool(J9CfrClassFile* classfile, U_8* data, U_8* dataEnd, U_8* segment, U_8*
12281228
return -2;
12291229
}
12301230
CHECK_EOF(size);
1231-
verifyResult = j9bcutil_verifyCanonisizeAndCopyUTF8(info->bytes, index, size);
1231+
verifyResult = j9bcutil_verifyCanonisizeAndCopyUTF8(info->bytes, index, size, &(info->flags1));
12321232
info->slot1 = (U_32) verifyResult;
1233-
if (verifyResult < 0) {
1233+
if ((verifyResult < 0) ||
1234+
(J9_ARE_ALL_BITS_SET(info->flags1, CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM) && (classfile->majorVersion >= 48))
1235+
) {
12341236
errorCode = J9NLS_CFR_ERR_BAD_UTF8__ID;
12351237
offset = (U_32) (index - data - 1);
12361238
goto _errorFound;
@@ -2587,7 +2589,7 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
25872589
goto _errorFound;
25882590
}
25892591

2590-
if((value & CFR_ACC_FINAL)&&(value & CFR_ACC_ABSTRACT)) {
2592+
if ((value & CFR_ACC_FINAL)&&(value & CFR_ACC_ABSTRACT)) {
25912593
errorCode = J9NLS_CFR_ERR_FINAL_ABSTRACT_CLASS__ID;
25922594
offset = endOfConstantPool;
25932595
goto _errorFound;
@@ -2602,39 +2604,47 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
26022604
}
26032605

26042606
value = classfile->thisClass;
2605-
if((!value)||(value >= classfile->constantPoolCount)) {
2607+
if ((!value)||(value >= classfile->constantPoolCount)) {
26062608
errorCode = J9NLS_CFR_ERR_BAD_INDEX__ID;
26072609
offset = endOfConstantPool + 2;
26082610
goto _errorFound;
26092611
}
26102612

2611-
if((classfile->constantPool)&&(classfile->constantPool[value].tag != CFR_CONSTANT_Class)) {
2613+
if ((classfile->constantPool) && (classfile->constantPool[value].tag != CFR_CONSTANT_Class)) {
26122614
errorCode = J9NLS_CFR_ERR_NOT_CLASS__ID;
26132615
offset = endOfConstantPool + 2;
26142616
goto _errorFound;
26152617
}
2618+
if ((classfile->constantPool) && (CFR_CONSTANT_Class == classfile->constantPool[value].tag)) {
2619+
value = classfile->constantPool[classfile->thisClass].slot1;
2620+
if (J9_ARE_ALL_BITS_SET(classfile->constantPool[value].flags1, CFR_FOUND_SEPARATOR_IN_MUE_FORM) && (classfile->majorVersion < 48)) {
2621+
errorCode = J9NLS_CFR_ERR_BAD_CLASS_NAME__ID;
2622+
offset = endOfConstantPool + 2;
2623+
goto _errorFound;
2624+
}
2625+
}
26162626

26172627
value = classfile->superClass;
2618-
if(value >= classfile->constantPoolCount) {
2628+
if (value >= classfile->constantPoolCount) {
26192629
errorCode = J9NLS_CFR_ERR_BAD_INDEX__ID;
26202630
offset = endOfConstantPool + 4;
26212631
goto _errorFound;
26222632
}
26232633

2624-
if(value == 0) {
2634+
if (0 == value) {
26252635
/* Check against j.l.O. */
26262636
if(!utf8Equal(&classfile->constantPool[classfile->constantPool[classfile->thisClass].slot1], "java/lang/Object", 16)) {
26272637
errorCode = J9NLS_CFR_ERR_NULL_SUPER__ID;
26282638
offset = endOfConstantPool + 4;
26292639
goto _errorFound;
26302640
}
2631-
} else if(classfile->constantPool[value].tag != CFR_CONSTANT_Class) {
2641+
} else if (classfile->constantPool[value].tag != CFR_CONSTANT_Class) {
26322642
errorCode = J9NLS_CFR_ERR_SUPER_NOT_CLASS__ID;
26332643
offset = endOfConstantPool + 4;
26342644
goto _errorFound;
26352645
}
26362646

2637-
for(i = 0; i < classfile->interfacesCount; i++) {
2647+
for (i = 0; i < classfile->interfacesCount; i++) {
26382648
U_32 j;
26392649
J9CfrConstantPoolInfo* cpInfo;
26402650
value = classfile->interfaces[i];
@@ -2662,7 +2672,7 @@ checkClass(J9PortLibrary *portLib, J9CfrClassFile* classfile, U_8* segment, U_32
26622672
}
26632673

26642674
/* Check that interfaces subclass object. */
2665-
if(classfile->accessFlags & CFR_ACC_INTERFACE) {
2675+
if (classfile->accessFlags & CFR_ACC_INTERFACE) {
26662676
/* Check against j.l.O. */
26672677
if(!utf8Equal(&classfile->constantPool[classfile->constantPool[classfile->superClass].slot1], "java/lang/Object", 16)) {
26682678
errorCode = J9NLS_CFR_ERR_INTERFACE_SUPER_NOT_OBJECT__ID;

runtime/bcutil/test/natives/bcunatives.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2001, 2014 IBM Corp. and others
2+
* Copyright (c) 2001, 2020 IBM Corp. and others
33
*
44
* This program and the accompanying materials are made available under
55
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -55,7 +55,7 @@ Java_com_ibm_j9_test_bcutil_TestNatives_verifyCanonisizeAndCopyUTF8(JNIEnv *env,
5555
src[i] = (char) jSrc[i];
5656
}
5757

58-
result = j9bcutil_verifyCanonisizeAndCopyUTF8(dest, src, length);
58+
result = j9bcutil_verifyCanonisizeAndCopyUTF8(dest, src, length, NULL);
5959

6060
for (i =0; i < length; i++) {
6161
jDest[i] = dest[i];

runtime/oti/bcutil_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,11 @@ j9bcutil_freeTranslationBuffers (J9PortLibrary * portLib, J9TranslationBufferSet
141141
* @param *dest
142142
* @param *source
143143
* @param length
144+
* @param mueAsciiStatus If any non-null ASCII characters are represented in modified UTF-8 2 byte format instead of in 1 byte
144145
* @return I_32
145146
*/
146147
I_32
147-
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length);
148+
j9bcutil_verifyCanonisizeAndCopyUTF8 (U_8 *dest, U_8 *source, U_32 length, U_8 *mueAsciiStatus);
148149

149150

150151
/**

runtime/oti/cfr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,9 @@ typedef struct J9CfrClassFile {
945945

946946
#define ANON_CLASSNAME_CHARACTER_SEPARATOR '/'
947947

948+
#define CFR_FOUND_CHARS_IN_EXTENDED_MUE_FORM 0x1
949+
#define CFR_FOUND_SEPARATOR_IN_MUE_FORM 0x2
950+
948951
#ifdef __cplusplus
949952
}
950953
#endif

0 commit comments

Comments
 (0)