From 77ef700d60bc1e2e1c2aece1e93e018440d0d126 Mon Sep 17 00:00:00 2001 From: Talia McCormick Date: Mon, 2 Apr 2018 14:34:28 -0400 Subject: [PATCH 1/3] [WIP] Adds static and dynamic verification for ConDy --- runtime/bcverify/bcverify.c | 2 +- runtime/bcverify/rtverify.c | 2 +- runtime/bcverify/staticverify.c | 28 ++++++++++++++++++++++++++-- runtime/bcverify/vrfyhelp.c | 11 ++++++++++- runtime/oti/bcverify_api.h | 2 +- runtime/oti/j9nonbuilder.h | 4 ++++ 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/runtime/bcverify/bcverify.c b/runtime/bcverify/bcverify.c index 9f2afe0c108..d7af33b1712 100644 --- a/runtime/bcverify/bcverify.c +++ b/runtime/bcverify/bcverify.c @@ -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 */ diff --git a/runtime/bcverify/rtverify.c b/runtime/bcverify/rtverify.c index 5917140019a..ed3e7387715 100644 --- a/runtime/bcverify/rtverify.c +++ b/runtime/bcverify/rtverify.c @@ -705,7 +705,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 */ diff --git a/runtime/bcverify/staticverify.c b/runtime/bcverify/staticverify.c index 82ffedc2fdc..468cc319d52 100644 --- a/runtime/bcverify/staticverify.c +++ b/runtime/bcverify/staticverify.c @@ -217,6 +217,8 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len case CFR_BC_ldc: case CFR_BC_ldc_w: + J9CfrConstantPoolInfo *constantDynamicNameAndSignature = NULL; + if (bc == CFR_BC_ldc) { NEXT_U8(index, bcIndex); } else { @@ -231,6 +233,10 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len info = &(classfile->constantPool[index]); tag = (UDATA) info->tag; + if (CFR_CONSTANT_Dynamic == tag) { + constantDynamicNameAndSignature = &classFile->constantPool[classFile->constantPool[info].slot2]; + } + if (!((tag == CFR_CONSTANT_Integer) || (tag == CFR_CONSTANT_Float) || (tag == CFR_CONSTANT_String) @@ -239,7 +245,13 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len || ((flags & BCT_MajorClassFileVersionMask) == 0))) || (((tag == CFR_CONSTANT_MethodType) || (tag == CFR_CONSTANT_MethodHandle)) && (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java7MajorVersionShifted) - || ((flags & BCT_MajorClassFileVersionMask) == 0))) )) { + || ((flags & BCT_MajorClassFileVersionMask) == 0))) + || ((tag == CFR_CONSTANT_Dynamic) + && (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted) + || ((flags & BCT_MajorClassFileVersionMask) == 0)) + && ('D' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1]) + && ('J' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1])) + )) { 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; @@ -248,6 +260,8 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len break; case CFR_BC_ldc2_w: + J9CfrConstantPoolInfo *constantDynamicNameAndSignature = NULL; + NEXT_U16(index, bcIndex); if ((!index) || (index >= cpCount - 1)) { errorType = J9NLS_CFR_ERR_BAD_INDEX__ID; @@ -257,8 +271,18 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len } info = &(classfile->constantPool[index]); tag = (UDATA) info->tag; + + if (CFR_CONSTANT_Dynamic == tag) { + constantDynamicNameAndSignature = &classFile->constantPool[classFile->constantPool[info].slot2]; + } if (!((tag == CFR_CONSTANT_Double) - || (tag == CFR_CONSTANT_Long))) { + || (tag == CFR_CONSTANT_Long) + || ((tag == CFR_CONSTANT_Dynamic) + && (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted) + || ((flags & BCT_MajorClassFileVersionMask) == 0)) + && ('D' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1]) + && ('J' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1])) + )) { 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; diff --git a/runtime/bcverify/vrfyhelp.c b/runtime/bcverify/vrfyhelp.c index f320ece751a..effdc4783aa 100644 --- a/runtime/bcverify/vrfyhelp.c +++ b/runtime/bcverify/vrfyhelp.c @@ -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: @@ -417,6 +417,15 @@ 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 *nameAndSignature = J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(romConstantDynamicRef); + U_8* signature = J9UTF8_DATA(nameAndSignature); + + /* The return value of a method follows the first ')' listed in its signature */ + while (*signature++ != ')'); + pushType(verifyData, signature, stackTop); + break; } return stackTop; diff --git a/runtime/oti/bcverify_api.h b/runtime/oti/bcverify_api.h index 7ca0c586a70..a07944dd1c6 100644 --- a/runtime/oti/bcverify_api.h +++ b/runtime/oti/bcverify_api.h @@ -452,7 +452,7 @@ pushFieldType(J9BytecodeVerificationData *verifyData, J9UTF8 * utf8string, UDATA * @return UDATA * */ UDATA * -pushLdcType(J9ROMClass * romClass, UDATA index, UDATA * stackTop); +pushLdcType(J9BytecodeVerificationData *verifyData, J9ROMClass * romClass, UDATA index, UDATA * stackTop); /** diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index dd01f5a6836..b400d8b8905 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -2133,6 +2133,8 @@ typedef struct J9ConstantPool { #define J9CPTYPE_INTERFACE_STATIC_METHOD 16 #define J9CPTYPE_INTERFACE_INSTANCE_METHOD 17 +#define J9CPTYPE_CONSTANT_DYNAMIC 18 + #define J9_CP_BITS_PER_DESCRIPTION 8 #define J9_CP_DESCRIPTIONS_PER_U32 4 #define J9_CP_DESCRIPTION_MASK 255 @@ -2239,6 +2241,8 @@ typedef struct J9ROMStringRef { #define J9ROMSTRINGREF_UTF8DATA(base) NNSRP_GET((base)->utf8Data, struct J9UTF8*) +#define J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(base) NNSRP_GET((base)->nameAndSignature, struct J9UTF8*) + typedef struct J9ROMFieldRef { U_32 classRefCPIndex; J9SRP nameAndSignature; From 8bc6a12be7131aa9cf13754f4c298bd55fb38853 Mon Sep 17 00:00:00 2001 From: Talia McCormick Date: Mon, 9 Apr 2018 11:43:54 -0400 Subject: [PATCH 2/3] [WIP] Adds initial changes to verification WIP - Copyright dates - Refactor ldc for more informative error messages - Remove definition of 'J9CPTYPE_CONSTANT_DYNAMIC ' value (defined in other PR) - Update description comments on pushLdcType(...) - Update pushLdcType to expect a constant dynamic to provide a field descriptor instead of a method signature - Rename variable constantDynamicNameAndSignature to constantDynamicSignature Signed-off-by: Talia McCormick --- runtime/bcverify/staticverify.c | 97 +++++++++++++--------- runtime/bcverify/vrfyhelp.c | 9 +- runtime/nls/cfre/cfrerr.nls | 46 ++++++++++ runtime/oti/bcverify_api.h | 3 +- runtime/oti/j9nonbuilder.h | 2 - runtime/verbose/errormessageframeworkcfr.c | 5 +- 6 files changed, 114 insertions(+), 48 deletions(-) diff --git a/runtime/bcverify/staticverify.c b/runtime/bcverify/staticverify.c index 468cc319d52..c46c2d4cede 100644 --- a/runtime/bcverify/staticverify.c +++ b/runtime/bcverify/staticverify.c @@ -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 @@ -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; @@ -217,8 +217,6 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len case CFR_BC_ldc: case CFR_BC_ldc_w: - J9CfrConstantPoolInfo *constantDynamicNameAndSignature = NULL; - if (bc == CFR_BC_ldc) { NEXT_U8(index, bcIndex); } else { @@ -233,34 +231,54 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len info = &(classfile->constantPool[index]); tag = (UDATA) info->tag; - if (CFR_CONSTANT_Dynamic == tag) { - constantDynamicNameAndSignature = &classFile->constantPool[classFile->constantPool[info].slot2]; - } - - 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))) - || ((tag == CFR_CONSTANT_Dynamic) - && (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted) - || ((flags & BCT_MajorClassFileVersionMask) == 0)) - && ('D' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1]) - && ('J' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1])) - )) { - errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT__ID; - /* Jazz 82615: Set the constant pool index to show up in the error message framework */ + 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) + ) { + errorType = J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V49__ID; + errorDataIndex = index; + goto _verifyError; + } + break; + case CFR_CONSTANT_MethodType: + case CFR_CONSTANT_MethodHandle: + if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java7MajorVersionShifted) + || ((flags & BCT_MajorClassFileVersionMask) == 0) + ) { + errorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51__ID; + errorDataIndex = index; + goto _verifyError; + } + break; + case CFR_CONSTANT_Dynamic: + 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__ID; + errorDataIndex = index; + goto _verifyError; + } else if (('D' == constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) + || ('J' == constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) + ) { + errorType = J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE; + errorDataIndex = index; + goto _verifyError; + } + break; + default: + errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID; errorDataIndex = index; goto _verifyError; } break; case CFR_BC_ldc2_w: - J9CfrConstantPoolInfo *constantDynamicNameAndSignature = NULL; NEXT_U16(index, bcIndex); if ((!index) || (index >= cpCount - 1)) { @@ -273,18 +291,21 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len tag = (UDATA) info->tag; if (CFR_CONSTANT_Dynamic == tag) { - constantDynamicNameAndSignature = &classFile->constantPool[classFile->constantPool[info].slot2]; - } - if (!((tag == CFR_CONSTANT_Double) - || (tag == CFR_CONSTANT_Long) - || ((tag == CFR_CONSTANT_Dynamic) - && (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java11MajorVersionShifted) - || ((flags & BCT_MajorClassFileVersionMask) == 0)) - && ('D' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1]) - && ('J' != constantDynamicNameAndSignature->bytes[constantDynamicNameAndSignature->slot1 - 1])) - )) { - errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT__ID; - /* Jazz 82615: Set the constant pool index to show up in the error message framework */ + 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[constantDynamicSignature->slot1 - 1]) + && ('J' != constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) + ) { + 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; } diff --git a/runtime/bcverify/vrfyhelp.c b/runtime/bcverify/vrfyhelp.c index effdc4783aa..81983806a6a 100644 --- a/runtime/bcverify/vrfyhelp.c +++ b/runtime/bcverify/vrfyhelp.c @@ -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 @@ -420,11 +420,8 @@ pushLdcType(J9BytecodeVerificationData *verifyData, J9ROMClass * romClass, UDATA case J9CPTYPE_CONSTANT_DYNAMIC: J9ROMConstantDynamicRef* romConstantDynamicRef = (J9ROMConstantDynamicRef *)(J9_ROM_CP_FROM_ROM_CLASS(romClass) + index); J9UTF8 *nameAndSignature = J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(romConstantDynamicRef); - U_8* signature = J9UTF8_DATA(nameAndSignature); - - /* The return value of a method follows the first ')' listed in its signature */ - while (*signature++ != ')'); - pushType(verifyData, signature, stackTop); + /* The signature referenced by a ConstantDynamic entry is a field descriptor */ + pushType(verifyData, J9UTF8_DATA(nameAndSignature), stackTop); break; } diff --git a/runtime/nls/cfre/cfrerr.nls b/runtime/nls/cfre/cfrerr.nls index 8521910e92e..4096a233aaa 100644 --- a/runtime/nls/cfre/cfrerr.nls +++ b/runtime/nls/cfre/cfrerr.nls @@ -1361,3 +1361,49 @@ 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. + +#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. + +#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. + +#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. + +#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. + +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. + +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. + +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. diff --git a/runtime/oti/bcverify_api.h b/runtime/oti/bcverify_api.h index a07944dd1c6..73c26531cb7 100644 --- a/runtime/oti/bcverify_api.h +++ b/runtime/oti/bcverify_api.h @@ -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 @@ -446,6 +446,7 @@ pushFieldType(J9BytecodeVerificationData *verifyData, J9UTF8 * utf8string, UDATA /** * @brief +* @param verifyData * @param romClass * @param index * @param stackTop diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index b400d8b8905..554fe307949 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -2133,8 +2133,6 @@ typedef struct J9ConstantPool { #define J9CPTYPE_INTERFACE_STATIC_METHOD 16 #define J9CPTYPE_INTERFACE_INSTANCE_METHOD 17 -#define J9CPTYPE_CONSTANT_DYNAMIC 18 - #define J9_CP_BITS_PER_DESCRIPTION 8 #define J9_CP_DESCRIPTIONS_PER_U32 4 #define J9_CP_DESCRIPTION_MASK 255 diff --git a/runtime/verbose/errormessageframeworkcfr.c b/runtime/verbose/errormessageframeworkcfr.c index f54b459ea5c..a202a6b999b 100644 --- a/runtime/verbose/errormessageframeworkcfr.c +++ b/runtime/verbose/errormessageframeworkcfr.c @@ -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 */ From 225a3a78a2f37a37c40ae8b660d10d8ce5954652 Mon Sep 17 00:00:00 2001 From: Talia McCormick Date: Mon, 9 Apr 2018 15:50:58 -0400 Subject: [PATCH 3/3] [WIP] Adds secondary changes to verification WIP - Refactor ldc error codes - Correct signature-check - Update J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE macro Signed-off-by: Talia McCormick --- runtime/bcverify/staticverify.c | 84 ++++++++++++++++----------------- runtime/bcverify/vrfyhelp.c | 4 +- runtime/oti/j9nonbuilder.h | 5 +- 3 files changed, 44 insertions(+), 49 deletions(-) diff --git a/runtime/bcverify/staticverify.c b/runtime/bcverify/staticverify.c index c46c2d4cede..f7f42ef1b2a 100644 --- a/runtime/bcverify/staticverify.c +++ b/runtime/bcverify/staticverify.c @@ -228,53 +228,51 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len errorDataIndex = index; goto _verifyError; } + info = &(classfile->constantPool[index]); tag = (UDATA) info->tag; - - 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) - ) { - errorType = J9NLS_CFR_ERR_CP_ENTRY_INVALID_BEFORE_V49__ID; - errorDataIndex = index; - goto _verifyError; - } - break; - case CFR_CONSTANT_MethodType: - case CFR_CONSTANT_MethodHandle: - if (((flags & BCT_MajorClassFileVersionMask) >= BCT_Java7MajorVersionShifted) - || ((flags & BCT_MajorClassFileVersionMask) == 0) - ) { - errorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V51__ID; - 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; } - break; - case CFR_CONSTANT_Dynamic: - 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__ID; - errorDataIndex = index; - goto _verifyError; - } else if (('D' == constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) - || ('J' == constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) - ) { - errorType = J9NLS_CFR_ERR_BC_LDC_CONSTANT_DYNAMIC_RETURNS_LONG_OR_DOUBLE; + if (0 != ldcErrorType) { + errorType = ldcErrorType; errorDataIndex = index; goto _verifyError; } - break; - default: - errorType = J9NLS_CFR_ERR_BC_LDC_NOT_CONSTANT_OR_CONSTANT_DYNAMIC__ID; - errorDataIndex = index; - goto _verifyError; } break; @@ -297,8 +295,8 @@ checkBytecodeStructure (J9CfrClassFile * classfile, UDATA methodIndex, UDATA len errorType = J9NLS_CFR_ERR_LDC_INDEX_INVALID_BEFORE_V55; errorDataIndex = index; goto _verifyError; - } else if (('D' != constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) - && ('J' != constantDynamicSignature->bytes[constantDynamicSignature->slot1 - 1]) + } else if (('D' != constantDynamicSignature->bytes[0]) + && ('J' != constantDynamicSignature->bytes[0]) ) { errorType = J9NLS_CFR_ERR_BC_LDC2_CONSTANT_DYNAMIC_NOT_LONG_OR_DOUBLE; errorDataIndex = index; diff --git a/runtime/bcverify/vrfyhelp.c b/runtime/bcverify/vrfyhelp.c index 81983806a6a..9922764eb52 100644 --- a/runtime/bcverify/vrfyhelp.c +++ b/runtime/bcverify/vrfyhelp.c @@ -419,9 +419,9 @@ pushLdcType(J9BytecodeVerificationData *verifyData, J9ROMClass * romClass, UDATA break; case J9CPTYPE_CONSTANT_DYNAMIC: J9ROMConstantDynamicRef* romConstantDynamicRef = (J9ROMConstantDynamicRef *)(J9_ROM_CP_FROM_ROM_CLASS(romClass) + index); - J9UTF8 *nameAndSignature = J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(romConstantDynamicRef); + J9UTF8 *signature = J9ROMNAMEANDSIGNATURE_SIGNATURE(J9ROMCONSTANTDYNAMICREF_NAMEANDSIGNATURE(romConstantDynamicRef)); /* The signature referenced by a ConstantDynamic entry is a field descriptor */ - pushType(verifyData, J9UTF8_DATA(nameAndSignature), stackTop); + pushType(verifyData, J9UTF8_DATA(signature), stackTop); break; } diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 554fe307949..ebfd94c6802 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -2239,15 +2239,12 @@ typedef struct J9ROMStringRef { #define J9ROMSTRINGREF_UTF8DATA(base) NNSRP_GET((base)->utf8Data, struct J9UTF8*) -#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 {