Tue, 12 Jul 2016 22:31:57 +0000
8042660: vm/mlvm/anonloader/stress/byteMutation failed with: assert(index >=0 && index < _length) failed: symbol index overflow
Summary: Detect zero length signatures and throw ClassFormatError before bad dereference occurs
Reviewed-by: hseigel
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Fri Jul 08 13:59:32 2016 +0100 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Tue Jul 12 22:31:57 2016 +0000 1.3 @@ -537,6 +537,9 @@ 1.4 int name_index = cp->name_ref_index_at(index); 1.5 Symbol* name = cp->symbol_at(name_index); 1.6 Symbol* sig = cp->symbol_at(sig_index); 1.7 + guarantee_property(sig->utf8_length() != 0, 1.8 + "Illegal zero length constant pool entry at %d in class %s", 1.9 + sig_index, CHECK_(nullHandle)); 1.10 if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) { 1.11 verify_legal_method_signature(name, sig, CHECK_(nullHandle)); 1.12 } else { 1.13 @@ -560,8 +563,9 @@ 1.14 verify_legal_field_name(name, CHECK_(nullHandle)); 1.15 if (_need_verify && _major_version >= JAVA_7_VERSION) { 1.16 // Signature is verified above, when iterating NameAndType_info. 1.17 - // Need only to be sure it's the right type. 1.18 - if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) { 1.19 + // Need only to be sure it's non-zero length and the right type. 1.20 + if (signature->utf8_length() == 0 || 1.21 + signature->byte_at(0) == JVM_SIGNATURE_FUNC) { 1.22 throwIllegalSignature( 1.23 "Field", name, signature, CHECK_(nullHandle)); 1.24 } 1.25 @@ -572,8 +576,9 @@ 1.26 verify_legal_method_name(name, CHECK_(nullHandle)); 1.27 if (_need_verify && _major_version >= JAVA_7_VERSION) { 1.28 // Signature is verified above, when iterating NameAndType_info. 1.29 - // Need only to be sure it's the right type. 1.30 - if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) { 1.31 + // Need only to be sure it's non-zero length and the right type. 1.32 + if (signature->utf8_length() == 0 || 1.33 + signature->byte_at(0) != JVM_SIGNATURE_FUNC) { 1.34 throwIllegalSignature( 1.35 "Method", name, signature, CHECK_(nullHandle)); 1.36 } 1.37 @@ -584,8 +589,7 @@ 1.38 // 4509014: If a class method name begins with '<', it must be "<init>". 1.39 assert(name != NULL, "method name in constant pool is null"); 1.40 unsigned int name_len = name->utf8_length(); 1.41 - assert(name_len > 0, "bad method name"); // already verified as legal name 1.42 - if (name->byte_at(0) == '<') { 1.43 + if (name_len != 0 && name->byte_at(0) == '<') { 1.44 if (name != vmSymbols::object_initializer_name()) { 1.45 classfile_parse_error( 1.46 "Bad method name at constant pool index %u in class file %s",
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/runtime/classFileParserBug/BadNameAndType.java Tue Jul 12 22:31:57 2016 +0000 2.3 @@ -0,0 +1,57 @@ 2.4 +/* 2.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +/* 2.29 + * @test 2.30 + * @bug 8042660 2.31 + * @summary Constant pool NameAndType entries must point to non-zero length Utf8 strings 2.32 + * @compile emptySigUtf8.jcod 2.33 + * @compile emptyNameUtf8.jcod 2.34 + * @run main/othervm -Xverify:all BadNameAndType 2.35 + */ 2.36 + 2.37 +// Test that a constant pool NameAndType descriptor_index and/or name_index 2.38 +// that points to a zero length Utf8 string causes a ClassFormatError. 2.39 +public class BadNameAndType { 2.40 + public static void main(String args[]) throws Throwable { 2.41 + 2.42 + System.out.println("Regression test for bug 8042660"); 2.43 + 2.44 + // Test descriptor_index pointing to zero-length string. 2.45 + try { 2.46 + Class newClass = Class.forName("emptySigUtf8"); 2.47 + throw new RuntimeException("Expected ClassFormatError exception not thrown"); 2.48 + } catch (java.lang.ClassFormatError e) { 2.49 + System.out.println("Test BadNameAndType passed test case emptySigUtf8"); 2.50 + } 2.51 + 2.52 + // Test name_index pointing to zero-length string. 2.53 + try { 2.54 + Class newClass = Class.forName("emptyNameUtf8"); 2.55 + throw new RuntimeException("Expected ClassFormatError exception not thrown"); 2.56 + } catch (java.lang.ClassFormatError e) { 2.57 + System.out.println("Test BadNameAndType passed test case emptyNameUtf8"); 2.58 + } 2.59 + } 2.60 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/runtime/classFileParserBug/emptyNameUtf8.jcod Tue Jul 12 22:31:57 2016 +0000 3.3 @@ -0,0 +1,131 @@ 3.4 +/* 3.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + * 3.26 + */ 3.27 + 3.28 +// This class has an illegal NameAndType at constant pool #4. It's illegal because 3.29 +// the Utf8 that it points to at #27 is a zero length string which is not a valid 3.30 +// name. Loading this class should cause a ClassFormatError exception. 3.31 +class emptyNameUtf8 { 3.32 + 0xCAFEBABE; 3.33 + 0; // minor version 3.34 + 52; // version 3.35 + [29] { // Constant Pool 3.36 + ; // first element is empty 3.37 + Method #6 #15; // #1 at 0x0A 3.38 + Field #16 #17; // #2 at 0x0F 3.39 + String #18; // #3 at 0x14 3.40 + NameAndType #27 #28; // #4 at 0x9F 3.41 + class #21; // #5 at 0x1C 3.42 + class #22; // #6 at 0x1F 3.43 + Utf8 "<init>"; // #7 at 0x22 3.44 + Utf8 "()V"; // #8 at 0x2B 3.45 + Utf8 "Code"; // #9 at 0x2E 3.46 + Utf8 "LineNumberTable"; // #10 at 0x35 3.47 + Utf8 "main"; // #11 at 0x47 3.48 + Utf8 "([Ljava/lang/String;)V"; // #12 at 0x4E 3.49 + Utf8 "SourceFile"; // #13 at 0x67 3.50 + Utf8 "emptyNameUtf8.java"; // #14 at 0x74 3.51 + NameAndType #7 #8; // #15 at 0x81 3.52 + class #23; // #16 at 0x86 3.53 + NameAndType #24 #25; // #17 at 0x89 3.54 + Utf8 "Hello World"; // #18 at 0x8E 3.55 + class #26; // #19 at 0x9C 3.56 + Method #19 #4; // #20 at 0x17 3.57 + Utf8 "emptyNameUtf8"; // #21 at 0xA4 3.58 + Utf8 "java/lang/Object"; // #22 at 0xAC 3.59 + Utf8 "java/lang/System"; // #23 at 0xBF 3.60 + Utf8 "out"; // #24 at 0xD2 3.61 + Utf8 "Ljava/io/PrintStream;"; // #25 at 0xD8 3.62 + Utf8 "java/io/PrintStream"; // #26 at 0xF0 3.63 + Utf8 ""; // #27 at 0x0106 3.64 + Utf8 "()V"; // #28 at 0x0110 3.65 + } // Constant Pool 3.66 + 3.67 + 0x0021; // access 3.68 + #5;// this_cpx 3.69 + #6;// super_cpx 3.70 + 3.71 + [0] { // Interfaces 3.72 + } // Interfaces 3.73 + 3.74 + [0] { // fields 3.75 + } // fields 3.76 + 3.77 + [2] { // methods 3.78 + { // Member at 0x0134 3.79 + 0x0001; // access 3.80 + #7; // name_cpx 3.81 + #8; // sig_cpx 3.82 + [1] { // Attributes 3.83 + Attr(#9, 29) { // Code at 0x013C 3.84 + 1; // max_stack 3.85 + 1; // max_locals 3.86 + Bytes[5]{ 3.87 + 0x2AB70001B1; 3.88 + }; 3.89 + [0] { // Traps 3.90 + } // end Traps 3.91 + [1] { // Attributes 3.92 + Attr(#10, 6) { // LineNumberTable at 0x0153 3.93 + [1] { // LineNumberTable 3.94 + 0 2; // at 0x015F 3.95 + } 3.96 + } // end LineNumberTable 3.97 + } // Attributes 3.98 + } // end Code 3.99 + } // Attributes 3.100 + } // Member 3.101 + ; 3.102 + { // Member at 0x015F 3.103 + 0x0009; // access 3.104 + #11; // name_cpx 3.105 + #12; // sig_cpx 3.106 + [1] { // Attributes 3.107 + Attr(#9, 37) { // Code at 0x0167 3.108 + 2; // max_stack 3.109 + 1; // max_locals 3.110 + Bytes[9]{ 3.111 + 0xB200021203B60004; 3.112 + 0xB1; 3.113 + }; 3.114 + [0] { // Traps 3.115 + } // end Traps 3.116 + [1] { // Attributes 3.117 + Attr(#10, 10) { // LineNumberTable at 0x0182 3.118 + [2] { // LineNumberTable 3.119 + 0 4; // at 0x018E 3.120 + 8 5; // at 0x0192 3.121 + } 3.122 + } // end LineNumberTable 3.123 + } // Attributes 3.124 + } // end Code 3.125 + } // Attributes 3.126 + } // Member 3.127 + } // methods 3.128 + 3.129 + [1] { // Attributes 3.130 + Attr(#13, 2) { // SourceFile at 0x0194 3.131 + #14; 3.132 + } // end SourceFile 3.133 + } // Attributes 3.134 +} // end class emptyNameUtf8
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/runtime/classFileParserBug/emptySigUtf8.jcod Tue Jul 12 22:31:57 2016 +0000 4.3 @@ -0,0 +1,131 @@ 4.4 +/* 4.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + * 4.26 + */ 4.27 + 4.28 +// This class has an illegal NameAndType at constant pool #4. It's illegal because 4.29 +// the type that it points to at #28 is a zero length Utf8 string which is not a 4.30 +// valid signature. Loading this class should cause a ClassFormatError exception. 4.31 +class emptySigUtf8 { 4.32 + 0xCAFEBABE; 4.33 + 0; // minor version 4.34 + 52; // version 4.35 + [29] { // Constant Pool 4.36 + ; // first element is empty 4.37 + Method #6 #15; // #1 at 0x0A 4.38 + Field #16 #17; // #2 at 0x0F 4.39 + String #18; // #3 at 0x14 4.40 + NameAndType #27 #28; // #4 at 0x9F 4.41 + class #21; // #5 at 0x1C 4.42 + class #22; // #6 at 0x1F 4.43 + Utf8 "<init>"; // #7 at 0x22 4.44 + Utf8 "()V"; // #8 at 0x2B 4.45 + Utf8 "Code"; // #9 at 0x2E 4.46 + Utf8 "LineNumberTable"; // #10 at 0x35 4.47 + Utf8 "main"; // #11 at 0x47 4.48 + Utf8 "([Ljava/lang/String;)V"; // #12 at 0x4E 4.49 + Utf8 "SourceFile"; // #13 at 0x67 4.50 + Utf8 "emptySigUtf8.java"; // #14 at 0x74 4.51 + NameAndType #7 #8; // #15 at 0x81 4.52 + class #23; // #16 at 0x86 4.53 + NameAndType #24 #25; // #17 at 0x89 4.54 + Utf8 "Hello World"; // #18 at 0x8E 4.55 + class #26; // #19 at 0x9C 4.56 + Method #19 #4; // #20 at 0x17 4.57 + Utf8 "emptySigUtf8"; // #21 at 0xA4 4.58 + Utf8 "java/lang/Object"; // #22 at 0xAC 4.59 + Utf8 "java/lang/System"; // #23 at 0xBF 4.60 + Utf8 "out"; // #24 at 0xD2 4.61 + Utf8 "Ljava/io/PrintStream;"; // #25 at 0xD8 4.62 + Utf8 "java/io/PrintStream"; // #26 at 0xF0 4.63 + Utf8 "hi"; // #27 at 0x0106 4.64 + Utf8 ""; // #28 at 0x0110 4.65 + } // Constant Pool 4.66 + 4.67 + 0x0021; // access 4.68 + #5;// this_cpx 4.69 + #6;// super_cpx 4.70 + 4.71 + [0] { // Interfaces 4.72 + } // Interfaces 4.73 + 4.74 + [0] { // fields 4.75 + } // fields 4.76 + 4.77 + [2] { // methods 4.78 + { // Member at 0x0134 4.79 + 0x0001; // access 4.80 + #7; // name_cpx 4.81 + #8; // sig_cpx 4.82 + [1] { // Attributes 4.83 + Attr(#9, 29) { // Code at 0x013C 4.84 + 1; // max_stack 4.85 + 1; // max_locals 4.86 + Bytes[5]{ 4.87 + 0x2AB70001B1; 4.88 + }; 4.89 + [0] { // Traps 4.90 + } // end Traps 4.91 + [1] { // Attributes 4.92 + Attr(#10, 6) { // LineNumberTable at 0x0153 4.93 + [1] { // LineNumberTable 4.94 + 0 2; // at 0x015F 4.95 + } 4.96 + } // end LineNumberTable 4.97 + } // Attributes 4.98 + } // end Code 4.99 + } // Attributes 4.100 + } // Member 4.101 + ; 4.102 + { // Member at 0x015F 4.103 + 0x0009; // access 4.104 + #11; // name_cpx 4.105 + #12; // sig_cpx 4.106 + [1] { // Attributes 4.107 + Attr(#9, 37) { // Code at 0x0167 4.108 + 2; // max_stack 4.109 + 1; // max_locals 4.110 + Bytes[9]{ 4.111 + 0xB200021203B60004; 4.112 + 0xB1; 4.113 + }; 4.114 + [0] { // Traps 4.115 + } // end Traps 4.116 + [1] { // Attributes 4.117 + Attr(#10, 10) { // LineNumberTable at 0x0182 4.118 + [2] { // LineNumberTable 4.119 + 0 4; // at 0x018E 4.120 + 8 5; // at 0x0192 4.121 + } 4.122 + } // end LineNumberTable 4.123 + } // Attributes 4.124 + } // end Code 4.125 + } // Attributes 4.126 + } // Member 4.127 + } // methods 4.128 + 4.129 + [1] { // Attributes 4.130 + Attr(#13, 2) { // SourceFile at 0x0194 4.131 + #14; 4.132 + } // end SourceFile 4.133 + } // Attributes 4.134 +} // end class emptySigUtf8