Fri, 27 Mar 2015 02:17:16 +0000
Merge
1.1 --- a/src/share/vm/classfile/verifier.cpp Thu Mar 26 14:36:42 2015 -0400 1.2 +++ b/src/share/vm/classfile/verifier.cpp Fri Mar 27 02:17:16 2015 +0000 1.3 @@ -655,6 +655,7 @@ 1.4 1.5 1.6 bool this_uninit = false; // Set to true when invokespecial <init> initialized 'this' 1.7 + bool verified_exc_handlers = false; 1.8 1.9 // Merge with the next instruction 1.10 { 1.11 @@ -686,6 +687,18 @@ 1.12 } 1.13 } 1.14 1.15 + // Look for possible jump target in exception handlers and see if it 1.16 + // matches current_frame. Do this check here for astore*, dstore*, 1.17 + // fstore*, istore*, and lstore* opcodes because they can change the type 1.18 + // state by adding a local. JVM Spec says that the incoming type state 1.19 + // should be used for this check. So, do the check here before a possible 1.20 + // local is added to the type state. 1.21 + if (Bytecodes::is_store_into_local(opcode) && bci >= ex_min && bci < ex_max) { 1.22 + verify_exception_handler_targets( 1.23 + bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this)); 1.24 + verified_exc_handlers = true; 1.25 + } 1.26 + 1.27 switch (opcode) { 1.28 case Bytecodes::_nop : 1.29 no_control_flow = false; break; 1.30 @@ -1662,9 +1675,13 @@ 1.31 } // end switch 1.32 } // end Merge with the next instruction 1.33 1.34 - // Look for possible jump target in exception handlers and see if it 1.35 - // matches current_frame 1.36 - if (bci >= ex_min && bci < ex_max) { 1.37 + // Look for possible jump target in exception handlers and see if it matches 1.38 + // current_frame. Don't do this check if it has already been done (for 1.39 + // ([a,d,f,i,l]store* opcodes). This check cannot be done earlier because 1.40 + // opcodes, such as invokespecial, may set the this_uninit flag. 1.41 + assert(!(verified_exc_handlers && this_uninit), 1.42 + "Exception handler targets got verified before this_uninit got set"); 1.43 + if (!verified_exc_handlers && bci >= ex_min && bci < ex_max) { 1.44 verify_exception_handler_targets( 1.45 bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this)); 1.46 }
2.1 --- a/src/share/vm/interpreter/bytecodes.hpp Thu Mar 26 14:36:42 2015 -0400 2.2 +++ b/src/share/vm/interpreter/bytecodes.hpp Fri Mar 27 02:17:16 2015 +0000 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -420,6 +420,7 @@ 2.11 static bool is_astore (Code code) { return (code == _astore || code == _astore_0 || code == _astore_1 2.12 || code == _astore_2 || code == _astore_3); } 2.13 2.14 + static bool is_store_into_local(Code code){ return (_istore <= code && code <= _astore_3); } 2.15 static bool is_const (Code code) { return (_aconst_null <= code && code <= _ldc2_w); } 2.16 static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0 2.17 || code == _fconst_0 || code == _dconst_0); }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/runtime/stackMapCheck/BadMap.jasm Fri Mar 27 02:17:16 2015 +0000 3.3 @@ -0,0 +1,152 @@ 3.4 + /* 3.5 + * Copyright (c) 2015, 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 +/* 3.29 + * This class should throw VerifyError because the StackMap for bytecode index 3.30 + * 45 (astore_2, line 123) is incorrect. The stack maps for bytecode indexes 45 3.31 + * and 49 (astore, line 133) do not match because 45 does not supply enough 3.32 + * locals to satisfy 49. 3.33 + * 3.34 + * The astore_2 bytecode at bytecode index 45 changes the type state, 3.35 + * preventing the stackmap mismatch. But, if the incoming type state is used, 3.36 + * as required by JVM Spec 8, then the verifier will detected the stackmap 3.37 + * mismatch, and throw VerifyError. 3.38 + */ 3.39 + 3.40 +super public class BadMap 3.41 + version 51:0 3.42 +{ 3.43 + 3.44 + 3.45 +public Method "<init>":"()V" 3.46 + stack 1 locals 1 3.47 +{ 3.48 + aload_0; 3.49 + invokespecial Method java/lang/Object."<init>":"()V"; 3.50 + return; 3.51 +} 3.52 + 3.53 +public static Method main:"([Ljava/lang/String;)V" 3.54 + throws java/lang/Throwable 3.55 + stack 0 locals 1 3.56 +{ 3.57 + return; 3.58 +} 3.59 + 3.60 +public static Method foo:"()V" 3.61 + stack 3 locals 5 3.62 +{ 3.63 + iconst_0; 3.64 + ifne L5; 3.65 + nop; 3.66 + try t7; 3.67 + L5: stack_frame_type full; 3.68 + aconst_null; 3.69 + dup; 3.70 + astore_0; 3.71 + astore_1; 3.72 + try t0; 3.73 + aconst_null; 3.74 + astore_0; 3.75 + endtry t0; 3.76 + goto L19; 3.77 + catch t0 java/io/IOException; 3.78 + stack_frame_type full; 3.79 + locals_map class java/lang/Object, null; 3.80 + stack_map class java/io/IOException; 3.81 + astore_2; 3.82 + aconst_null; 3.83 + dup; 3.84 + astore_1; 3.85 + astore_0; 3.86 + try t1; 3.87 + L19: stack_frame_type full; 3.88 + locals_map class java/lang/Object, class java/lang/Object; 3.89 + aconst_null; 3.90 + astore_2; 3.91 + endtry t1; 3.92 + aload_1; 3.93 + ifnonnull L37; 3.94 + nop; 3.95 + goto L37; 3.96 + catch t1 #0; 3.97 + catch t2 #0; 3.98 + try t2; 3.99 + stack_frame_type full; 3.100 + locals_map class java/lang/Object, class java/lang/Object; 3.101 + stack_map class java/lang/Throwable; 3.102 + astore_3; 3.103 + endtry t2; 3.104 + aload_1; 3.105 + ifnonnull L35; 3.106 + nop; 3.107 + L35: stack_frame_type full; 3.108 + locals_map class java/lang/Object, class java/lang/Object, bogus, class java/lang/Throwable; 3.109 + aload_3; 3.110 + athrow; 3.111 + try t3, t4; 3.112 + L37: stack_frame_type full; 3.113 + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; 3.114 + aload_1; 3.115 + ifnonnull L42; 3.116 + nop; 3.117 + endtry t3, t4; 3.118 + L42: stack_frame_type full; 3.119 + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; 3.120 + goto L54; 3.121 + catch t3 java/lang/Exception; 3.122 + try t5; 3.123 + stack_frame_type full; 3.124 + locals_map class java/lang/Object, class java/lang/Object; 3.125 + stack_map class java/lang/Exception; 3.126 + astore_2; // astore_2, at bci 45, that changes the type state. 3.127 + endtry t5; 3.128 + goto L54; 3.129 + catch t4 #0; 3.130 + catch t5 #0; 3.131 + catch t6 #0; 3.132 + try t6; 3.133 + stack_frame_type full; 3.134 + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; 3.135 + stack_map class java/lang/Throwable; 3.136 + astore 4; 3.137 + endtry t6; 3.138 + aload 4; 3.139 + athrow; 3.140 + L54: stack_frame_type full; 3.141 + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; 3.142 + goto L57; 3.143 + L57: stack_frame_type full; 3.144 + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; 3.145 + nop; 3.146 + endtry t7; 3.147 + return; 3.148 + catch t7 #0; 3.149 + stack_frame_type full; 3.150 + stack_map class java/lang/Throwable; 3.151 + nop; 3.152 + athrow; 3.153 +} 3.154 + 3.155 +} // end Class BadMap
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/runtime/stackMapCheck/BadMapDstore.jasm Fri Mar 27 02:17:16 2015 +0000 4.3 @@ -0,0 +1,79 @@ 4.4 + /* 4.5 + * Copyright (c) 2015, 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 +/* 4.29 + * This class should throw VerifyError because the StackMap for bytecode index 4.30 + * 9 (dstore_2, line 60) is incorrect. The stack maps for bytecode indexes 9 4.31 + * and 18 (astore_2, line 70) do not match because 9 does not supply enough 4.32 + * locals to satisfy 18. 4.33 + * 4.34 + * The dstore_2 bytecode at bytecode index 9 changes the type state, 4.35 + * preventing the stackmap mismatch. But, if the incoming type state is used, 4.36 + * as required by JVM Spec 8, then the verifier will detected the stackmap 4.37 + * mismatch, and throw VerifyError. 4.38 + */ 4.39 + 4.40 +super public class BadMapDstore 4.41 + version 51:0 4.42 +{ 4.43 + 4.44 +Field blah:I; 4.45 + 4.46 +public Method "<init>":"()V" 4.47 + stack 1 locals 1 4.48 +{ 4.49 + aload_0; 4.50 + invokespecial Method java/lang/Object."<init>":"()V"; 4.51 + return; 4.52 +} 4.53 + 4.54 +public static Method main:"([Ljava/lang/String;)V" 4.55 + stack 4 locals 4 4.56 +{ 4.57 + new class BadMapDstore; 4.58 + dup; 4.59 + invokespecial Method "<init>":"()V"; 4.60 + astore_1; 4.61 + dconst_1; 4.62 + try t0; 4.63 + dstore_2; 4.64 + aload_1; 4.65 + iconst_5; 4.66 + putfield Field blah:"I"; 4.67 + endtry t0; 4.68 + goto L22; 4.69 + catch t0 java/lang/Throwable; 4.70 + stack_frame_type full; 4.71 + locals_map class "[Ljava/lang/String;", class BadMapDstore, double; 4.72 + stack_map class java/lang/Throwable; 4.73 + astore_2; 4.74 + aload_1; 4.75 + dconst_0; 4.76 + dstore_2; 4.77 + pop; 4.78 + L22: stack_frame_type same; 4.79 + return; 4.80 +} 4.81 + 4.82 +} // end Class BadMapDstore
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/runtime/stackMapCheck/BadMapIstore.jasm Fri Mar 27 02:17:16 2015 +0000 5.3 @@ -0,0 +1,79 @@ 5.4 + /* 5.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + * 5.26 + */ 5.27 + 5.28 +/* 5.29 + * This class should throw VerifyError because the StackMap for bytecode index 5.30 + * 9 (istore_2, line 60) is incorrect. The stack maps for bytecode indexes 9 5.31 + * and 18 (astore_2, line 70) do not match because 9 does not supply enough 5.32 + * locals to satisfy 18. 5.33 + * 5.34 + * The istore_2 bytecode at bytecode index 9 changes the type state, 5.35 + * preventing the stackmap mismatch. But, if the incoming type state is used, 5.36 + * as required by JVM Spec 8, then the verifier will detected the stackmap 5.37 + * mismatch, and throw VerifyError. 5.38 + */ 5.39 + 5.40 +super public class BadMapIstore 5.41 + version 51:0 5.42 +{ 5.43 + 5.44 +Field blah:I; 5.45 + 5.46 +public Method "<init>":"()V" 5.47 + stack 1 locals 1 5.48 +{ 5.49 + aload_0; 5.50 + invokespecial Method java/lang/Object."<init>":"()V"; 5.51 + return; 5.52 +} 5.53 + 5.54 +public static Method main:"([Ljava/lang/String;)V" 5.55 + stack 2 locals 3 5.56 +{ 5.57 + new class BadMapIstore; 5.58 + dup; 5.59 + invokespecial Method "<init>":"()V"; 5.60 + astore_1; 5.61 + iconst_2; 5.62 + try t0; 5.63 + istore_2; 5.64 + aload_1; 5.65 + iconst_5; 5.66 + putfield Field blah:"I"; 5.67 + endtry t0; 5.68 + goto L22; 5.69 + catch t0 java/lang/Throwable; 5.70 + stack_frame_type full; 5.71 + locals_map class "[Ljava/lang/String;", class BadMapIstore, int; 5.72 + stack_map class java/lang/Throwable; 5.73 + astore_2; 5.74 + aload_1; 5.75 + iconst_4; 5.76 + istore_2; 5.77 + pop; 5.78 + L22: stack_frame_type same; 5.79 + return; 5.80 +} 5.81 + 5.82 +} // end Class BadMapIstore
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/runtime/stackMapCheck/StackMapCheck.java Fri Mar 27 02:17:16 2015 +0000 6.3 @@ -0,0 +1,63 @@ 6.4 + /* 6.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + * 6.26 + */ 6.27 + 6.28 +/* 6.29 + * @test 6.30 + * @bug 7127066 6.31 + * @summary Class verifier accepts an invalid class file 6.32 + * @compile BadMap.jasm 6.33 + * @compile BadMapDstore.jasm 6.34 + * @compile BadMapIstore.jasm 6.35 + * @run main/othervm -Xverify:all StackMapCheck 6.36 + */ 6.37 + 6.38 +public class StackMapCheck { 6.39 + public static void main(String args[]) throws Throwable { 6.40 + 6.41 + System.out.println("Regression test for bug 7127066"); 6.42 + try { 6.43 + Class newClass = Class.forName("BadMap"); 6.44 + throw new RuntimeException( 6.45 + "StackMapCheck failed, BadMap did not throw VerifyError"); 6.46 + } catch (java.lang.VerifyError e) { 6.47 + System.out.println("BadMap passed, VerifyError was thrown"); 6.48 + } 6.49 + 6.50 + try { 6.51 + Class newClass = Class.forName("BadMapDstore"); 6.52 + throw new RuntimeException( 6.53 + "StackMapCheck failed, BadMapDstore did not throw VerifyError"); 6.54 + } catch (java.lang.VerifyError e) { 6.55 + System.out.println("BadMapDstore passed, VerifyError was thrown"); 6.56 + } 6.57 + 6.58 + try { 6.59 + Class newClass = Class.forName("BadMapIstore"); 6.60 + throw new RuntimeException( 6.61 + "StackMapCheck failed, BadMapIstore did not throw VerifyError"); 6.62 + } catch (java.lang.VerifyError e) { 6.63 + System.out.println("BadMapIstore passed, VerifyError was thrown"); 6.64 + } 6.65 + } 6.66 +}