Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8280155: [PPC64, s390] frame size checks are not yet correct #797

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,8 +280,60 @@ void frame::patch_pc(Thread* thread, address pc) {
}

bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
// Is there anything to do?
assert(is_interpreted_frame(), "Not an interpreted frame");
// These are reasonable sanity checks
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
return false;
}
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
int min_frame_slots = (abi_minframe_size + ijava_state_size) / sizeof(intptr_t);
if (fp() - min_frame_slots < sp()) {
return false;
}
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
return false;
}

// do some validation of frame elements

// first the method

Method* m = *interpreter_frame_method_addr();

// validate the method we'd find in this potential sender
if (!Method::is_valid_method(m)) return false;

// stack frames shouldn't be much larger than max_stack elements
// this test requires the use of unextended_sp which is the sp as seen by
// the current frame, and not sp which is the "raw" pc which could point
// further because of local variables of the callee method inserted after
// method arguments
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}

// validate bci/bcx

address bcp = interpreter_frame_bcp();
if (m->validate_bci_from_bcp(bcp) < 0) {
return false;
}

// validate constantPoolCache*
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
if (MetaspaceObj::is_valid(cp) == false) return false;

// validate locals

address locals = (address) *interpreter_frame_locals_addr();

if (locals > thread->stack_base() || locals < (address) fp()) return false;

// We'd have to be pretty unlucky to be mislead at this point
return true;
}

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -295,8 +295,60 @@ void frame::patch_pc(Thread* thread, address pc) {
}

bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
// Is there anything to do?
assert(is_interpreted_frame(), "Not an interpreted frame");
// These are reasonable sanity checks
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
return false;
}
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
int min_frame_slots = (z_abi_16_size + z_ijava_state_size) / sizeof(intptr_t);
if (fp() - min_frame_slots < sp()) {
return false;
}
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
return false;
}

// do some validation of frame elements

// first the method

Method* m = *interpreter_frame_method_addr();

// validate the method we'd find in this potential sender
if (!Method::is_valid_method(m)) return false;

// stack frames shouldn't be much larger than max_stack elements
// this test requires the use of unextended_sp which is the sp as seen by
// the current frame, and not sp which is the "raw" pc which could point
// further because of local variables of the callee method inserted after
// method arguments
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}

// validate bci/bcx

address bcp = interpreter_frame_bcp();
if (m->validate_bci_from_bcp(bcp) < 0) {
return false;
}

// validate constantPoolCache*
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
if (MetaspaceObj::is_valid(cp) == false) return false;

// validate locals

address locals = (address) *interpreter_frame_locals_addr();

if (locals > thread->stack_base() || locals < (address) fp()) return false;

// We'd have to be pretty unlucky to be mislead at this point
return true;
}

@@ -152,7 +152,9 @@ bool os::Aix::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* u
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context(uc);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// get_frame_at_stack_banging_point() is only called when we
// have well defined stacks so java_sender() calls do not need
// to assert safe_for_sender() first.
*fr = fr->java_sender();
}
} else {
@@ -169,7 +171,7 @@ bool os::Aix::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* u
address lr = ucontext_get_lr(uc);
*fr = frame(sp, lr);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// See java_sender() comment above.
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}
@@ -172,7 +172,9 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t*
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context(uc);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// get_frame_at_stack_banging_point() is only called when we
// have well defined stacks so java_sender() calls do not need
// to assert safe_for_sender() first.
*fr = fr->java_sender();
}
} else {
@@ -189,7 +191,7 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t*
address lr = ucontext_get_lr(uc);
*fr = frame(sp, lr);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// See java_sender() comment above.
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,14 +58,15 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
// if we were running Java code when SIGPROF came in.
if (isInJava) {
ucontext_t* uc = (ucontext_t*) ucontext;
frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/],
(address)uc->uc_mcontext.regs->nip);
address pc = (address)uc->uc_mcontext.regs->nip;

if (ret_frame.pc() == NULL) {
if (pc == NULL) {
// ucontext wasn't useful
return false;
}

frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], pc);

if (ret_frame.fp() == NULL) {
// The found frame does not have a valid frame pointer.
// Bail out because this will create big trouble later on, either
@@ -154,7 +154,9 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t*
// method returns the Java sender of the current frame.
*fr = os::fetch_frame_from_context(uc);
if (!fr->is_first_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// get_frame_at_stack_banging_point() is only called when we
// have well defined stacks so java_sender() calls do not need
// to assert safe_for_sender() first.
*fr = fr->java_sender();
}
} else {
@@ -171,7 +173,7 @@ bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t*
address lr = ucontext_get_lr(uc);
*fr = frame(sp, lr);
if (!fr->is_java_frame()) {
assert(fr->safe_for_sender(thread), "Safety check");
// See java_sender() comment above.
assert(!fr->is_first_frame(), "Safety check");
*fr = fr->java_sender();
}