Skip to content
Permalink
Browse files

8234372: Investigate use of Thread::stack_base() and queries for "in …

…stack"

Reviewed-by: dcubed, stuefe
  • Loading branch information
David Holmes
David Holmes committed Feb 13, 2020
1 parent 25c5a23 commit 4e4d1f2b4dad61b4c4590f1d3a956b9ad86ff74c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -59,16 +59,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
address unextended_sp = (address)_unextended_sp;

// consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;

// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size);


if (!sp_safe) {
if (!thread->is_in_usable_stack(sp)) {
return false;
}

@@ -566,7 +558,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {

address locals = (address) *interpreter_frame_locals_addr();

if (locals > thread->stack_base() || locals < (address) fp()) return false;
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,5 +1,5 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. 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
@@ -57,21 +57,14 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;

static size_t stack_guard_size = os::uses_stack_guard_pages() ?
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;

// consider stack guards when trying to determine "safe" stack pointers
// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp != NULL &&
(sp <= thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size));

if (!sp_safe) {
if (!thread->is_in_usable_stack(sp)) {
return false;
}

bool unextended_sp_safe = (unextended_sp != NULL &&
(unextended_sp <= thread->stack_base()) &&
(unextended_sp < thread->stack_base()) &&
(unextended_sp >= sp));
if (!unextended_sp_safe) {
return false;
@@ -80,7 +73,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// We know sp/unextended_sp are safe. Only fp is questionable here.

bool fp_safe = (fp != NULL &&
(fp <= thread->stack_base()) &&
(fp < thread->stack_base()) &&
fp >= sp);

if (_cb != NULL ) {
@@ -148,7 +141,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// is really a frame pointer.

intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);

if (!saved_fp_safe) {
return false;
@@ -178,7 +171,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp >= sender_sp);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);

if (!saved_fp_safe) {
return false;
@@ -191,7 +184,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();

bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > (address)sender.fp());
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());

return jcw_safe;
}
@@ -501,7 +494,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {

address locals = (address) *interpreter_frame_locals_addr();

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

// We'd have to be pretty unlucky to be mislead at this point

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -55,17 +55,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;

// Consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_reserved_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;

// consider stack guards when trying to determine "safe" stack pointers
// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size);


if (!sp_safe) {
if (!thread->is_in_usable_stack(sp)) {
return false;
}

@@ -77,10 +69,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
}

// An fp must be within the stack and above (but not equal) sp.
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
// An interpreter fp must be within the stack and above (but not equal) sp.
// Moreover, it must be at least the size of the ijava_state structure.
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) &&
bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
((fp - sp) >= ijava_state_size);

// We know sp/unextended_sp are safe, only fp is questionable here
@@ -140,7 +132,7 @@ bool frame::safe_for_sender(JavaThread *thread) {

// sender_fp must be within the stack and above (but not
// equal) current frame's fp.
if (sender_fp > thread->stack_base() || sender_fp <= fp) {
if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
return false;
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -59,17 +59,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;

// Consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_reserved_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;

// consider stack guards when trying to determine "safe" stack pointers
// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size);


if (!sp_safe) {
if (!thread->is_in_usable_stack(sp)) {
return false;
}

@@ -81,10 +73,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
}

// An fp must be within the stack and above (but not equal) sp.
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
// An interpreter fp must be within the stack and above (but not equal) sp.
// Moreover, it must be at least the size of the z_ijava_state structure.
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) &&
bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
((fp - sp) >= z_ijava_state_size);

// We know sp/unextended_sp are safe, only fp is questionable here
@@ -144,7 +136,7 @@ bool frame::safe_for_sender(JavaThread *thread) {

// sender_fp must be within the stack and above (but not
// equal) current frame's fp.
if (sender_fp > thread->stack_base() || sender_fp <= fp) {
if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
return false;
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. 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
@@ -177,22 +177,21 @@ bool frame::safe_for_sender(JavaThread *thread) {
address _SP = (address) sp();
address _FP = (address) fp();
address _UNEXTENDED_SP = (address) unextended_sp();
// sp must be within the stack
bool sp_safe = (_SP <= thread->stack_base()) &&
(_SP >= thread->stack_base() - thread->stack_size());

if (!sp_safe) {
// consider stack guards when trying to determine "safe" stack pointers
// sp must be within the usable part of the stack (not in guards)
if (!thread->is_in_usable_stack(_SP)) {
return false;
}

// unextended sp must be within the stack and above or equal sp
bool unextended_sp_safe = (_UNEXTENDED_SP <= thread->stack_base()) &&
bool unextended_sp_safe = (_UNEXTENDED_SP < thread->stack_base()) &&
(_UNEXTENDED_SP >= _SP);

if (!unextended_sp_safe) return false;

// an fp must be within the stack and above (but not equal) sp
bool fp_safe = (_FP <= thread->stack_base()) &&
bool fp_safe = (_FP < thread->stack_base()) &&
(_FP > _SP);

// We know sp/unextended_sp are safe only fp is questionable here
@@ -252,7 +251,7 @@ bool frame::safe_for_sender(JavaThread *thread) {

// an fp must be within the stack and above (but not equal) current frame's _FP

bool sender_fp_safe = (sender_fp <= thread->stack_base()) &&
bool sender_fp_safe = (sender_fp < thread->stack_base()) &&
(sender_fp > _FP);

if (!sender_fp_safe) {
@@ -280,7 +279,7 @@ bool frame::safe_for_sender(JavaThread *thread) {

address jcw = (address)sender.entry_frame_call_wrapper();

bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > sender_fp);
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > sender_fp);

return jcw_safe;
}
@@ -672,7 +671,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {

address locals = (address) *interpreter_frame_locals_addr();

if (locals > thread->stack_base() || locals < (address) fp()) return false;
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,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. 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
@@ -57,16 +57,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
address unextended_sp = (address)_unextended_sp;

// consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;

// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size);


if (!sp_safe) {
if (!thread->is_in_usable_stack(sp)) {
return false;
}

@@ -553,7 +545,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {

address locals = (address) *interpreter_frame_locals_addr();

if (locals > thread->stack_base() || locals < (address) fp()) return false;
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,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. 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
@@ -719,7 +719,7 @@ bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
assert(t->osthread()->expanding_stack(), "expand should be set");
assert(t->stack_base() != NULL, "stack_base was not initialized");

if (addr < t->stack_base() && addr >= t->stack_reserved_zone_base()) {
if (t->is_in_usable_stack(addr)) {
sigset_t mask_all, old_sigset;
sigfillset(&mask_all);
pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. 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
@@ -2542,7 +2542,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
//
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
if (addr > thread->stack_reserved_zone_base() && addr < thread->stack_base()) {
if (thread->is_in_usable_stack(addr)) {
addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
os::commit_memory((char *)addr, thread->stack_base() - addr,
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. 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
@@ -336,8 +336,7 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
return 1;
}
// check if fault address is within thread stack
if (addr < thread->stack_base() &&
addr >= thread->stack_base() - thread->stack_size()) {
if (thread->on_local_stack(addr)) {
// stack overflow
if (thread->in_stack_yellow_reserved_zone(addr)) {
thread->disable_stack_yellow_reserved_zone();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -63,7 +63,7 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,

if (ret_frame.is_interpreted_frame()) {
frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked();
if (stack_base() >= (address)istate && (address)istate > stack_end()) {
if (on_local_stack((address)istate)) {
return false;
}
const Method *m = (const Method*)(istate->method);

0 comments on commit 4e4d1f2

Please sign in to comment.