Skip to content

Commit

Permalink
Adds static and dynamic verification for ConDy
Browse files Browse the repository at this point in the history
- Add validation to ldc ldc_w and ldc2_w for ConstantDynamic entry
- Check that the Condy return type matches the bytecode
- Refactor ldc with more informative error messages
- Update description comments on pushLdcType(...)
- Update pushLdcType to expect a constant dynamic to provide a field
- Refactor ldc error codes

Code by Talia McCormick from eclipse-openj9#1631

Signed-off-by: Jack Lu <[email protected]>
  • Loading branch information
Talia McCormick authored and fengxue-IS committed Sep 7, 2018
1 parent 7e094bb commit 2caef91
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 29 deletions.
2 changes: 1 addition & 1 deletion runtime/bcverify/bcverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -1510,7 +1510,7 @@ simulateStack (J9BytecodeVerificationData * verifyData)
} else {
index = PARAM_16(bcIndex, 1);
}
stackTop = pushLdcType(romClass, index, stackTop);
stackTop = pushLdcType(verifyData, romClass, index, stackTop);
break;

/* Change lookup table to generate constant of correct type */
Expand Down
2 changes: 1 addition & 1 deletion runtime/bcverify/rtverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
} else {
index = PARAM_16(bcIndex, 1);
}
stackTop = pushLdcType(romClass, index, stackTop);
stackTop = pushLdcType(verifyData, romClass, index, stackTop);
break;

/* Change lookup table to generate constant of correct type */
Expand Down
83 changes: 63 additions & 20 deletions runtime/bcverify/staticverify.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2017 IBM Corp. and others
* Copyright (c) 1991, 2018 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 @@ -167,7 +167,7 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len
U_8 *bcStart, *bcInstructionStart, *bcIndex, *bcEnd;
UDATA bc, index, u1, u2, i, maxLocals, cpCount, tag, firstKey;
UDATA sigChar;
UDATA errorType;
UDATA errorType = 0;
UDATA errorDataIndex = 0;


Expand Down Expand Up @@ -228,26 +228,56 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len
errorDataIndex = index;
goto _verifyError;
}

info = &(classfile->constantPool[index]);
tag = (UDATA) info->tag;

if (!((tag == CFR_CONSTANT_Integer)
|| (tag == CFR_CONSTANT_Float)
|| (tag == CFR_CONSTANT_String)
|| ((tag == CFR_CONSTANT_Class)
&& (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java5MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0)))
|| (((tag == CFR_CONSTANT_MethodType) || (tag == CFR_CONSTANT_MethodHandle))
&& (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java7MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0))) )) {
errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT__ID;
/* Jazz 82615: Set the constant pool index to show up in the error message framework */
errorDataIndex = index;
goto _verifyError;
{
UDATA ldcErrorType = 0;
switch (tag) {
case CFR_CONSTANT_Integer:
case CFR_CONSTANT_Float:
case CFR_CONSTANT_String:
break;
case CFR_CONSTANT_Class:
if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java5MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0)
) {
ldcErrorType = J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V49__ID;
}
break;
case CFR_CONSTANT_MethodType:
case CFR_CONSTANT_MethodHandle:
if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java7MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0)
) {
ldcErrorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51__ID;
}
break;
case CFR_CONSTANT_Dynamic:
J9CfrConstantPoolInfo *constantDynamicSignature = &classfile->constantPool[classFile->constantPool[info->slot2].slot2];
if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0)
) {
ldcErrorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55__ID;
} else if (('D' == constantDynamicSignature->bytes[0])
|| ('J' == constantDynamicSignature->bytes[0])
) {
ldcErrorType = J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE;
}
break;
default:
ldcErrorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID;
}
if (0 != ldcErrorType) {
errorType = ldcErrorType;
errorDataIndex = index;
goto _verifyError;
}
}
break;

case CFR_BC_ldc2_w:

NEXT_U16(index, bcIndex);
if ((!index) || (index >= cpCount - 1)) {
errorType = J9NLS_CFR_ERR_BAD_INDEX__ID;
Expand All @@ -257,10 +287,23 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len
}
info = &(classfile->constantPool[index]);
tag = (UDATA) info->tag;
if (!((tag == CFR_CONSTANT_Double)
|| (tag == CFR_CONSTANT_Long))) {
errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT__ID;
/* Jazz 82615: Set the constant pool index to show up in the error message framework */

if (CFR_CONSTANT_Dynamic == tag) {
J9CfrConstantPoolInfo *constantDynamicSignature = &classfile->constantPool[classFile->constantPool[info->slot2].slot2];
if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted)
|| ((flags & BCT_MajorClassFileVersionMask) == 0)) {
errorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55;
errorDataIndex = index;
goto _verifyError;
} else if (('D' != constantDynamicSignature->bytes[0])
&& ('J' != constantDynamicSignature->bytes[0])
) {
errorType = J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE;
errorDataIndex = index;
goto _verifyError;
}
} else if ((CFR_CONSTANT_Double != tag) && (CFR_CONSTANT_Long != tag)) {
errorType = J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID;
errorDataIndex = index;
goto _verifyError;
}
Expand Down
10 changes: 8 additions & 2 deletions runtime/bcverify/vrfyhelp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2017 IBM Corp. and others
* Copyright (c) 1991, 8IBM 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 @@ -396,7 +396,7 @@ initializeClassNameList(J9BytecodeVerificationData *verifyData)


UDATA *
pushLdcType(J9ROMClass * romClass, UDATA index, UDATA * stackTop)
pushLdcType(J9BytecodeVerificationData *verifyData, J9ROMClass * romClass, UDATA index, UDATA * stackTop)
{
switch(J9_CP_TYPE(J9ROMCLASS_CPSHAPEDESCRIPTION(romClass), index)) {
case J9CPTYPE_CLASS:
Expand All @@ -417,6 +417,12 @@ pushLdcType(J9ROMClass * romClass, UDATA index, UDATA * stackTop)
case J9CPTYPE_METHODHANDLE:
PUSH(BCV_JAVA_LANG_INVOKE_METHODHANDLE_INDEX << BCV_CLASS_INDEX_SHIFT);
break;
case J9CPTYPE_CONSTANT_DYNAMIC:
J9ROMConstantDynamicRef* romConstantDynamicRef = (J9ROMConstantDynamicRef *)(J9_ROM_CP_FROM_ROM_CLASS(romClass) + index);
J9UTF8 *signature = J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(romConstantDynamicRef));
/* The signature referenced by a ConstantDynamic entry is a field descriptor */
pushType(verifyData, J9UTF8_DATA(signature), stackTop);
break;
}

return stackTop;
Expand Down
61 changes: 61 additions & 0 deletions runtime/nls/cfre/cfrerr.nls
Original file line number Diff line number Diff line change
Expand Up @@ -1361,4 +1361,65 @@ J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V55=Constant pool entry not valid in class
J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V55.explanation=Please consult the Java Virtual Machine Specification for a detailed explaination.
J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V55.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V55.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

#ldc and ldc_w are not translatable
J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC=The ldc and ldc_2 bytecodes must reference a constant or a constant dynamic
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.explanation=An 'ldc' or 'ldc_w' bytecode can only reference constant values or a constant dynamic entry.
J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

#ldc2_w is not translatable
J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC=The ldc2_w bytecode must reference a constant or a constant dynamic
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.explanation=An 'ldc2_w' bytecode can only reference constant values or a constant dynamic entry.
J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

#ldc and ldc_w are not translatable
J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE=Constant dynamic entries referenced by the ldc and ldc_w bytecodes must not return long or double
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE.explanation=An 'ldc' or 'ldc_w' bytecode can only reference constant values or a constant dynamic entry.
J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

#ldc2_w is not translatable
J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE=Constant dynamic entries referenced by the ldc2_w bytecode must return long or double
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE.explanation=An 'ldc2_w' bytecode can only reference constant values or a constant dynamic entry.
J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V49=Constant pool entry not valid in class files with versions < 49.0
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V49.explanation=Please consult the Java Virtual Machine Specification for a detailed explaination.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V49.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V49.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51=Constant pool entry not valid in class files with versions < 51.0
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51.explanation=Please consult the Java Virtual Machine Specification for a detailed explaination.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE

J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55=Constant pool entry not valid in class files with versions < 55.0
# START NON-TRANSLATABLE
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55.explanation=Please consult the Java Virtual Machine Specification for a detailed explaination.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55.system_action=The JVM will throw a verification or classloading-related exception such as java.lang.ClassFormatError.
J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55.user_response=Contact the provider of the classfile for a corrected version.

# END NON-TRANSLATABLE
5 changes: 3 additions & 2 deletions runtime/oti/bcverify_api.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2017 IBM Corp. and others
* Copyright (c) 1991, 2018 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 @@ -446,13 +446,14 @@ pushFieldType(J9BytecodeVerificationData *verifyData, J9UTF8 * utf8string, UDATA

/**
* @brief
* @param verifyData
* @param romClass
* @param index
* @param stackTop
* @return UDATA *
*/
UDATA *
pushLdcType(J9ROMClass * romClass, UDATA index, UDATA * stackTop);
pushLdcType(J9BytecodeVerificationData *verifyData, J9ROMClass * romClass, UDATA index, UDATA * stackTop);


/**
Expand Down
5 changes: 3 additions & 2 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2246,13 +2246,14 @@ typedef struct J9ROMConstantDynamicRef {
U_32 bsmIndexAndCpType;
} J9ROMConstantDynamicRef;

#define J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(base) NNSRP_GET((base)->nameAndSignature, struct J9UTF8*)

typedef struct J9ROMFieldRef {
U_32 classRefCPIndex;
J9SRP nameAndSignature;
} J9ROMFieldRef;

#define J9ROMFIELDREF_NAMEANDSIGNATURE(base) NNSRP_GET((base)->nameAndSignature, struct J9ROMNameAndSignature*)

#define J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(base) NNSRP_GET((base)->nameAndSignature, struct J9ROMNameAndSignature*)
/* @ddr_namespace: map_to_type=J9ROMMethodHandleRef */

typedef struct J9ROMMethodHandleRef {
Expand Down
5 changes: 4 additions & 1 deletion runtime/verbose/errormessageframeworkcfr.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,10 @@ printJ9CfrErrorMessages(MessageBuffer* msgBuf, J9CfrError* error, MethodContextI
case J9NLS_CFR_ERR_BAD_INDEX__ID:
printMessage(msgBuf, "Constant pool index %u is invalid.", error->errorDataIndex);
break;
case J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_LDC2_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_NEW_NOT_CLASS__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_ANEWARRAY_NOT_CLASS__ID: /* FALLTHROUGH */
case J9NLS_CFR_ERR_BC_CHECKCAST_NOT_CLASS__ID: /* FALLTHROUGH */
Expand Down

0 comments on commit 2caef91

Please sign in to comment.