Mon, 17 Mar 2014 10:17:55 -0400
8035119: Fix exceptions to bytecode verification
Summary: Prevent ctor calls to super() and this() from avoidable code (try blocks, if stmts, etc.)
Reviewed-by: coleenp, acorn, mschoene
1.1 --- a/src/share/vm/classfile/stackMapTable.cpp Tue Mar 11 14:02:23 2014 -0700 1.2 +++ b/src/share/vm/classfile/stackMapTable.cpp Mon Mar 17 10:17:55 2014 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -134,6 +134,7 @@ 1.11 } 1.12 // check if uninitialized objects exist on backward branches 1.13 check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); 1.14 + frame->verifier()->update_furthest_jump(target); 1.15 } 1.16 1.17 void StackMapTable::check_new_object(
2.1 --- a/src/share/vm/classfile/verifier.cpp Tue Mar 11 14:02:23 2014 -0700 2.2 +++ b/src/share/vm/classfile/verifier.cpp Mon Mar 17 10:17:55 2014 -0400 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1998, 2014, 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 @@ -632,6 +632,9 @@ 2.11 bool no_control_flow = false; // Set to true when there is no direct control 2.12 // flow from current instruction to the next 2.13 // instruction in sequence 2.14 + 2.15 + set_furthest_jump(0); 2.16 + 2.17 Bytecodes::Code opcode; 2.18 while (!bcs.is_last_bytecode()) { 2.19 // Check for recursive re-verification before each bytecode. 2.20 @@ -2245,6 +2248,29 @@ 2.21 "Bad <init> method call"); 2.22 return; 2.23 } 2.24 + 2.25 + // Make sure that this call is not jumped over. 2.26 + if (bci < furthest_jump()) { 2.27 + verify_error(ErrorContext::bad_code(bci), 2.28 + "Bad <init> method call from inside of a branch"); 2.29 + return; 2.30 + } 2.31 + 2.32 + // Make sure that this call is not done from within a TRY block because 2.33 + // that can result in returning an incomplete object. Simply checking 2.34 + // (bci >= start_pc) also ensures that this call is not done after a TRY 2.35 + // block. That is also illegal because this call must be the first Java 2.36 + // statement in the constructor. 2.37 + ExceptionTable exhandlers(_method()); 2.38 + int exlength = exhandlers.length(); 2.39 + for(int i = 0; i < exlength; i++) { 2.40 + if (bci >= exhandlers.start_pc(i)) { 2.41 + verify_error(ErrorContext::bad_code(bci), 2.42 + "Bad <init> method call from after the start of a try block"); 2.43 + return; 2.44 + } 2.45 + } 2.46 + 2.47 current_frame->initialize_object(type, current_type()); 2.48 *this_uninit = true; 2.49 } else if (type.is_uninitialized()) {
3.1 --- a/src/share/vm/classfile/verifier.hpp Tue Mar 11 14:02:23 2014 -0700 3.2 +++ b/src/share/vm/classfile/verifier.hpp Mon Mar 17 10:17:55 2014 -0400 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -258,6 +258,9 @@ 3.11 3.12 ErrorContext _error_context; // contains information about an error 3.13 3.14 + // Used to detect illegal jumps over calls to super() nd this() in ctors. 3.15 + int32_t _furthest_jump; 3.16 + 3.17 void verify_method(methodHandle method, TRAPS); 3.18 char* generate_code_data(methodHandle m, u4 code_length, TRAPS); 3.19 void verify_exception_handler_table(u4 code_length, char* code_data, 3.20 @@ -403,6 +406,20 @@ 3.21 Symbol* create_temporary_symbol(const char *s, int length, TRAPS); 3.22 3.23 TypeOrigin ref_ctx(const char* str, TRAPS); 3.24 + 3.25 + // Keep track of the furthest branch done in a method to make sure that 3.26 + // there are no branches over calls to super() or this() from inside of 3.27 + // a constructor. 3.28 + int32_t furthest_jump() { return _furthest_jump; } 3.29 + 3.30 + void set_furthest_jump(int32_t target) { 3.31 + _furthest_jump = target; 3.32 + } 3.33 + 3.34 + void update_furthest_jump(int32_t target) { 3.35 + if (target > _furthest_jump) _furthest_jump = target; 3.36 + } 3.37 + 3.38 }; 3.39 3.40 inline int ClassVerifier::change_sig_to_verificationType(