mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 12:04:39 +02:00
6756528: Bytecodes::special_length_at reads past end of code buffer
Add end-of-buffer indicator for paths used by the verifier Reviewed-by: acorn, coleenp
This commit is contained in:
parent
107bbcc8f4
commit
7de6d649be
3 changed files with 29 additions and 10 deletions
|
@ -28,8 +28,9 @@
|
|||
Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
|
||||
assert(!is_last_bytecode(), "should have been checked");
|
||||
// set next bytecode position
|
||||
address bcp = RawBytecodeStream::bcp();
|
||||
int l = Bytecodes::raw_special_length_at(bcp);
|
||||
address bcp = RawBytecodeStream::bcp();
|
||||
address end = method()->code_base() + end_bci();
|
||||
int l = Bytecodes::raw_special_length_at(bcp, end);
|
||||
if (l <= 0 || (_bci + l) > _end_bci) {
|
||||
code = Bytecodes::_illegal;
|
||||
} else {
|
||||
|
@ -39,8 +40,12 @@ Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
|
|||
_is_wide = false;
|
||||
// check for special (uncommon) cases
|
||||
if (code == Bytecodes::_wide) {
|
||||
code = (Bytecodes::Code)bcp[1];
|
||||
_is_wide = true;
|
||||
if (bcp + 1 >= end) {
|
||||
code = Bytecodes::_illegal;
|
||||
} else {
|
||||
code = (Bytecodes::Code)bcp[1];
|
||||
_is_wide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_code = code;
|
||||
|
|
|
@ -54,13 +54,19 @@ Bytecodes::Code Bytecodes::non_breakpoint_code_at(address bcp, methodOop method)
|
|||
return method->orig_bytecode_at(method->bci_from(bcp));
|
||||
}
|
||||
|
||||
int Bytecodes::special_length_at(address bcp) {
|
||||
int Bytecodes::special_length_at(address bcp, address end) {
|
||||
Code code = code_at(bcp);
|
||||
switch (code) {
|
||||
case _wide:
|
||||
if (end != NULL && bcp + 1 >= end) {
|
||||
return -1; // don't read past end of code buffer
|
||||
}
|
||||
return wide_length_for(cast(*(bcp + 1)));
|
||||
case _tableswitch:
|
||||
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
||||
if (end != NULL && aligned_bcp + 3*jintSize >= end) {
|
||||
return -1; // don't read past end of code buffer
|
||||
}
|
||||
jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
|
||||
jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
|
||||
jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
|
||||
|
@ -73,6 +79,9 @@ int Bytecodes::special_length_at(address bcp) {
|
|||
case _fast_binaryswitch: // fall through
|
||||
case _fast_linearswitch:
|
||||
{ address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
|
||||
if (end != NULL && aligned_bcp + 2*jintSize >= end) {
|
||||
return -1; // don't read past end of code buffer
|
||||
}
|
||||
jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
|
||||
jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
|
||||
// only return len if it can be represented as a positive int;
|
||||
|
@ -90,14 +99,17 @@ int Bytecodes::special_length_at(address bcp) {
|
|||
// verifier when reading in bytecode to verify. Other mechanisms that
|
||||
// run at runtime (such as generateOopMaps) need to iterate over the code
|
||||
// and don't expect to see breakpoints: they want to see the instruction
|
||||
// which was replaces so that they can get the correct length and find
|
||||
// which was replaced so that they can get the correct length and find
|
||||
// the next bytecode.
|
||||
int Bytecodes::raw_special_length_at(address bcp) {
|
||||
//
|
||||
// 'end' indicates the end of the code buffer, which we should not try to read
|
||||
// past.
|
||||
int Bytecodes::raw_special_length_at(address bcp, address end) {
|
||||
Code code = code_or_bp_at(bcp);
|
||||
if (code == _breakpoint) {
|
||||
return 1;
|
||||
} else {
|
||||
return special_length_at(bcp);
|
||||
return special_length_at(bcp, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -340,8 +340,10 @@ class Bytecodes: AllStatic {
|
|||
const char* wf = wide_format(code);
|
||||
return (wf == NULL) ? 0 : (int)strlen(wf);
|
||||
}
|
||||
static int special_length_at(address bcp);
|
||||
static int raw_special_length_at(address bcp);
|
||||
// if 'end' is provided, it indicates the end of the code buffer which
|
||||
// should not be read past when parsing.
|
||||
static int special_length_at(address bcp, address end = NULL);
|
||||
static int raw_special_length_at(address bcp, address end = NULL);
|
||||
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
||||
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
||||
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue