8197429: Increased stack guard causes segfaults on x86-32
Reviewed-by: dholmes
This commit is contained in:
parent
9523d40461
commit
f48f7c36d5
@ -97,6 +97,7 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
|
|||||||
BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
|
BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
|
||||||
$(TOPDIR)/test/hotspot/jtreg/runtime/execstack \
|
$(TOPDIR)/test/hotspot/jtreg/runtime/execstack \
|
||||||
$(TOPDIR)/test/hotspot/jtreg/runtime/jsig \
|
$(TOPDIR)/test/hotspot/jtreg/runtime/jsig \
|
||||||
|
$(TOPDIR)/test/hotspot/jtreg/runtime/StackGap \
|
||||||
$(TOPDIR)/test/hotspot/jtreg/runtime/StackGuardPages
|
$(TOPDIR)/test/hotspot/jtreg/runtime/StackGuardPages
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
|
|||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rw := -z noexecstack
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rw := -z noexecstack
|
||||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rwx := -z execstack
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rwx := -z execstack
|
||||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread
|
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread
|
||||||
|
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exestack-gap := -ljvm -lpthread
|
||||||
BUILD_TEST_invoke_exeinvoke.c_OPTIMIZATION := NONE
|
BUILD_TEST_invoke_exeinvoke.c_OPTIMIZATION := NONE
|
||||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl
|
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl
|
||||||
endif
|
endif
|
||||||
|
@ -629,6 +629,10 @@ static void NOINLINE _expand_stack_to(address bottom) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void os::Linux::expand_stack_to(address bottom) {
|
||||||
|
_expand_stack_to(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
|
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
|
||||||
assert(t!=NULL, "just checking");
|
assert(t!=NULL, "just checking");
|
||||||
assert(t->osthread()->expanding_stack(), "expand should be set");
|
assert(t->osthread()->expanding_stack(), "expand should be set");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -218,6 +218,8 @@ class Linux {
|
|||||||
// none present
|
// none present
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void expand_stack_to(address bottom);
|
||||||
|
|
||||||
typedef int (*sched_getcpu_func_t)(void);
|
typedef int (*sched_getcpu_func_t)(void);
|
||||||
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
|
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
|
||||||
typedef int (*numa_max_node_func_t)(void);
|
typedef int (*numa_max_node_func_t)(void);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -834,6 +834,28 @@ void os::verify_stack_alignment() {
|
|||||||
void os::workaround_expand_exec_shield_cs_limit() {
|
void os::workaround_expand_exec_shield_cs_limit() {
|
||||||
#if defined(IA32)
|
#if defined(IA32)
|
||||||
size_t page_size = os::vm_page_size();
|
size_t page_size = os::vm_page_size();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JDK-8197429
|
||||||
|
*
|
||||||
|
* Expand the stack mapping to the end of the initial stack before
|
||||||
|
* attempting to install the codebuf. This is needed because newer
|
||||||
|
* Linux kernels impose a distance of a megabyte between stack
|
||||||
|
* memory and other memory regions. If we try to install the
|
||||||
|
* codebuf before expanding the stack the installation will appear
|
||||||
|
* to succeed but we'll get a segfault later if we expand the stack
|
||||||
|
* in Java code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (os::is_primordial_thread()) {
|
||||||
|
address limit = Linux::initial_thread_stack_bottom();
|
||||||
|
if (! DisablePrimordialThreadGuardPages) {
|
||||||
|
limit += JavaThread::stack_red_zone_size() +
|
||||||
|
JavaThread::stack_yellow_zone_size();
|
||||||
|
}
|
||||||
|
os::Linux::expand_stack_to(limit);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Take the highest VA the OS will give us and exec
|
* Take the highest VA the OS will give us and exec
|
||||||
*
|
*
|
||||||
@ -852,6 +874,16 @@ void os::workaround_expand_exec_shield_cs_limit() {
|
|||||||
char* hint = (char*)(Linux::initial_thread_stack_bottom() -
|
char* hint = (char*)(Linux::initial_thread_stack_bottom() -
|
||||||
(JavaThread::stack_guard_zone_size() + page_size));
|
(JavaThread::stack_guard_zone_size() + page_size));
|
||||||
char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
|
char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
|
||||||
|
|
||||||
|
if (codebuf == NULL) {
|
||||||
|
// JDK-8197429: There may be a stack gap of one megabyte between
|
||||||
|
// the limit of the stack and the nearest memory region: this is a
|
||||||
|
// Linux kernel workaround for CVE-2017-1000364. If we failed to
|
||||||
|
// map our codebuf, try again at an address one megabyte lower.
|
||||||
|
hint -= 1 * M;
|
||||||
|
codebuf = os::attempt_reserve_memory_at(page_size, hint);
|
||||||
|
}
|
||||||
|
|
||||||
if ((codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true))) {
|
if ((codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true))) {
|
||||||
return; // No matter, we tried, best effort.
|
return; // No matter, we tried, best effort.
|
||||||
}
|
}
|
||||||
|
33
test/hotspot/jtreg/runtime/StackGap/T.java
Normal file
33
test/hotspot/jtreg/runtime/StackGap/T.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Red Hat, Inc. 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class T {
|
||||||
|
|
||||||
|
public static void test(int n) {
|
||||||
|
if (n == 0) return;
|
||||||
|
System.out.println (n);
|
||||||
|
test (n - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
test/hotspot/jtreg/runtime/StackGap/exestack-gap.c
Normal file
74
test/hotspot/jtreg/runtime/StackGap/exestack-gap.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Red Hat, Inc. 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
JNIEnv* create_vm(JavaVM **jvm, char *extra_option)
|
||||||
|
{
|
||||||
|
JNIEnv* env;
|
||||||
|
JavaVMInitArgs args;
|
||||||
|
JavaVMOption options[4];
|
||||||
|
args.version = JNI_VERSION_1_8;
|
||||||
|
args.nOptions = 3 + (extra_option != NULL);
|
||||||
|
options[0].optionString = "-Xss2048k";
|
||||||
|
char classpath[4096];
|
||||||
|
snprintf(classpath, sizeof classpath,
|
||||||
|
"-Djava.class.path=%s", getenv("CLASSPATH"));
|
||||||
|
options[1].optionString = classpath;
|
||||||
|
options[2].optionString = "-XX:+UnlockExperimentalVMOptions";
|
||||||
|
if (extra_option) {
|
||||||
|
options[3].optionString = extra_option;
|
||||||
|
}
|
||||||
|
args.options = &options[0];
|
||||||
|
args.ignoreUnrecognized = 0;
|
||||||
|
int rv;
|
||||||
|
rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
|
||||||
|
if (rv < 0) return NULL;
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run(char *extra_arg) {
|
||||||
|
JavaVM *jvm;
|
||||||
|
jclass T_class;
|
||||||
|
jmethodID test_method;
|
||||||
|
JNIEnv *env = create_vm(&jvm, extra_arg);
|
||||||
|
if (env == NULL)
|
||||||
|
exit(1);
|
||||||
|
T_class = (*env)->FindClass(env, "T");
|
||||||
|
test_method = (*env)->GetStaticMethodID(env, T_class, "test", "(I)V");
|
||||||
|
(*env)->CallStaticVoidMethod(env, T_class, test_method, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 1) {
|
||||||
|
run(argv[1]);
|
||||||
|
} else {
|
||||||
|
run(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
49
test/hotspot/jtreg/runtime/StackGap/testme.sh
Normal file
49
test/hotspot/jtreg/runtime/StackGap/testme.sh
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Copyright (c) 2014, 2018, 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
|
||||||
|
# under the terms of the GNU General Public License version 2 only, as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
# accompanied this code).
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License version
|
||||||
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
# or visit www.oracle.com if you need additional information or have any
|
||||||
|
# questions.
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# @test testme.sh
|
||||||
|
# @summary Linux kernel stack guard should not cause segfaults on x86-32
|
||||||
|
# @compile T.java
|
||||||
|
# @run shell testme.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ "${TESTSRC}" = "" ]
|
||||||
|
then
|
||||||
|
TESTSRC=${PWD}
|
||||||
|
echo "TESTSRC not set. Using "${TESTSRC}" as default"
|
||||||
|
fi
|
||||||
|
echo "TESTSRC=${TESTSRC}"
|
||||||
|
## Adding common setup Variables for running shell tests.
|
||||||
|
. ${TESTSRC}/../../test_env.sh
|
||||||
|
|
||||||
|
if [ "${VM_OS}" != "linux" ]
|
||||||
|
then
|
||||||
|
echo "Test only valid for Linux"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=.:${TESTJAVA}/lib/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH
|
||||||
|
export LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
${TESTNATIVEPATH}/stack-gap || exit $?
|
||||||
|
${TESTNATIVEPATH}/stack-gap -XX:+DisablePrimordialThreadGuardPages || exit $?
|
Loading…
Reference in New Issue
Block a user