8035119: Fix exceptions to bytecode verification

Mon, 17 Mar 2014 10:17:55 -0400

author
hseigel
date
Mon, 17 Mar 2014 10:17:55 -0400
changeset 6761
aff11567504c
parent 6760
cc7a96a360d0
child 6762
5f7e12f5b4e5

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

src/share/vm/classfile/stackMapTable.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/verifier.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/verifier.hpp file | annotate | diff | comparison | revisions
     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(

mercurial