6756528: Bytecodes::special_length_at reads past end of code buffer

Thu, 30 Oct 2008 15:48:59 -0400

author
kamg
date
Thu, 30 Oct 2008 15:48:59 -0400
changeset 848
c7ec737733a6
parent 845
8fb16f199266
child 849
348be627a148

6756528: Bytecodes::special_length_at reads past end of code buffer
Summary: Add end-of-buffer indicator for paths used by the verifier
Reviewed-by: acorn, coleenp

src/share/vm/interpreter/bytecodeStream.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/bytecodes.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/bytecodes.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/interpreter/bytecodeStream.cpp	Wed Oct 22 20:47:00 2008 -0700
     1.2 +++ b/src/share/vm/interpreter/bytecodeStream.cpp	Thu Oct 30 15:48:59 2008 -0400
     1.3 @@ -28,8 +28,9 @@
     1.4  Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
     1.5    assert(!is_last_bytecode(), "should have been checked");
     1.6    // set next bytecode position
     1.7 -  address bcp  = RawBytecodeStream::bcp();
     1.8 -  int l = Bytecodes::raw_special_length_at(bcp);
     1.9 +  address bcp = RawBytecodeStream::bcp();
    1.10 +  address end = method()->code_base() + end_bci();
    1.11 +  int l = Bytecodes::raw_special_length_at(bcp, end);
    1.12    if (l <= 0 || (_bci + l) > _end_bci) {
    1.13      code = Bytecodes::_illegal;
    1.14    } else {
    1.15 @@ -39,8 +40,12 @@
    1.16      _is_wide = false;
    1.17      // check for special (uncommon) cases
    1.18      if (code == Bytecodes::_wide) {
    1.19 -      code = (Bytecodes::Code)bcp[1];
    1.20 -      _is_wide = true;
    1.21 +      if (bcp + 1 >= end) {
    1.22 +        code = Bytecodes::_illegal;
    1.23 +      } else {
    1.24 +        code = (Bytecodes::Code)bcp[1];
    1.25 +        _is_wide = true;
    1.26 +      }
    1.27      }
    1.28    }
    1.29    _code = code;
     2.1 --- a/src/share/vm/interpreter/bytecodes.cpp	Wed Oct 22 20:47:00 2008 -0700
     2.2 +++ b/src/share/vm/interpreter/bytecodes.cpp	Thu Oct 30 15:48:59 2008 -0400
     2.3 @@ -54,13 +54,19 @@
     2.4    return method->orig_bytecode_at(method->bci_from(bcp));
     2.5  }
     2.6  
     2.7 -int Bytecodes::special_length_at(address bcp) {
     2.8 +int Bytecodes::special_length_at(address bcp, address end) {
     2.9    Code code = code_at(bcp);
    2.10    switch (code) {
    2.11    case _wide:
    2.12 +    if (end != NULL && bcp + 1 >= end) {
    2.13 +      return -1; // don't read past end of code buffer
    2.14 +    }
    2.15      return wide_length_for(cast(*(bcp + 1)));
    2.16    case _tableswitch:
    2.17      { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
    2.18 +      if (end != NULL && aligned_bcp + 3*jintSize >= end) {
    2.19 +        return -1; // don't read past end of code buffer
    2.20 +      }
    2.21        jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
    2.22        jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
    2.23        jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
    2.24 @@ -73,6 +79,9 @@
    2.25    case _fast_binaryswitch: // fall through
    2.26    case _fast_linearswitch:
    2.27      { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
    2.28 +      if (end != NULL && aligned_bcp + 2*jintSize >= end) {
    2.29 +        return -1; // don't read past end of code buffer
    2.30 +      }
    2.31        jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
    2.32        jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
    2.33        // only return len if it can be represented as a positive int;
    2.34 @@ -90,14 +99,17 @@
    2.35  // verifier when reading in bytecode to verify.  Other mechanisms that
    2.36  // run at runtime (such as generateOopMaps) need to iterate over the code
    2.37  // and don't expect to see breakpoints: they want to see the instruction
    2.38 -// which was replaces so that they can get the correct length and find
    2.39 +// which was replaced so that they can get the correct length and find
    2.40  // the next bytecode.
    2.41 -int Bytecodes::raw_special_length_at(address bcp) {
    2.42 +//
    2.43 +// 'end' indicates the end of the code buffer, which we should not try to read
    2.44 +// past.
    2.45 +int Bytecodes::raw_special_length_at(address bcp, address end) {
    2.46    Code code = code_or_bp_at(bcp);
    2.47    if (code == _breakpoint) {
    2.48      return 1;
    2.49    } else {
    2.50 -    return special_length_at(bcp);
    2.51 +    return special_length_at(bcp, end);
    2.52    }
    2.53  }
    2.54  
     3.1 --- a/src/share/vm/interpreter/bytecodes.hpp	Wed Oct 22 20:47:00 2008 -0700
     3.2 +++ b/src/share/vm/interpreter/bytecodes.hpp	Thu Oct 30 15:48:59 2008 -0400
     3.3 @@ -340,8 +340,10 @@
     3.4      const char* wf = wide_format(code);
     3.5      return (wf == NULL) ? 0 : (int)strlen(wf);
     3.6    }
     3.7 -  static int         special_length_at(address bcp);
     3.8 -  static int         raw_special_length_at(address bcp);
     3.9 +  // if 'end' is provided, it indicates the end of the code buffer which
    3.10 +  // should not be read past when parsing.
    3.11 +  static int         special_length_at(address bcp, address end = NULL);
    3.12 +  static int         raw_special_length_at(address bcp, address end = NULL);
    3.13    static int         length_at      (address bcp)  { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
    3.14    static int         java_length_at (address bcp)  { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
    3.15    static bool        is_java_code   (Code code)    { return 0 <= code && code < number_of_java_codes; }

mercurial