aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkamg <none@none>2011-03-02 08:18:35 -0500
committerkamg <none@none>2011-03-02 08:18:35 -0500
commit841d549ec664f966e03e5477902512676ec9af11 (patch)
tree44c39cfff5d936f4f3d45b6269b4303ae694528d
parent25de85724fbfcd10ba1d9f498c586fe3f24b4f74 (diff)
6878713: Verifier heap corruption, relating to backward jsrs
Summary: Added overflow detection in arena Amalloc methods Reviewed-by: coleenp, phh
-rw-r--r--src/share/vm/memory/allocation.cpp9
-rw-r--r--src/share/vm/memory/allocation.hpp12
-rw-r--r--src/share/vm/utilities/globalDefinitions_gcc.hpp1
-rw-r--r--src/share/vm/utilities/globalDefinitions_sparcWorks.hpp11
-rw-r--r--src/share/vm/utilities/globalDefinitions_visCPP.hpp9
-rw-r--r--test/runtime/6878713/Test6878713.sh74
-rw-r--r--test/runtime/6878713/testcase.jarbin0 -> 984 bytes
7 files changed, 114 insertions, 2 deletions
diff --git a/src/share/vm/memory/allocation.cpp b/src/share/vm/memory/allocation.cpp
index 02197c5b6..19cb8df66 100644
--- a/src/share/vm/memory/allocation.cpp
+++ b/src/share/vm/memory/allocation.cpp
@@ -422,6 +422,9 @@ size_t Arena::used() const {
return sum; // Return total consumed space.
}
+void Arena::signal_out_of_memory(size_t sz, const char* whence) const {
+ vm_exit_out_of_memory(sz, whence);
+}
// Grow a new Chunk
void* Arena::grow( size_t x ) {
@@ -431,8 +434,9 @@ void* Arena::grow( size_t x ) {
Chunk *k = _chunk; // Get filled-up chunk address
_chunk = new (len) Chunk(len);
- if (_chunk == NULL)
- vm_exit_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
+ if (_chunk == NULL) {
+ signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
+ }
if (k) k->set_next(_chunk); // Append new chunk to end of linked list
else _first = _chunk;
@@ -529,6 +533,7 @@ void* Arena::malloc(size_t size) {
// for debugging with UseMallocOnly
void* Arena::internal_malloc_4(size_t x) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
+ check_for_overflow(x, "Arena::internal_malloc_4");
if (_hwm + x > _max) {
return grow(x);
} else {
diff --git a/src/share/vm/memory/allocation.hpp b/src/share/vm/memory/allocation.hpp
index 2c6845cd9..a9147083c 100644
--- a/src/share/vm/memory/allocation.hpp
+++ b/src/share/vm/memory/allocation.hpp
@@ -207,6 +207,15 @@ protected:
debug_only(void* malloc(size_t size);)
debug_only(void* internal_malloc_4(size_t x);)
NOT_PRODUCT(void inc_bytes_allocated(size_t x);)
+
+ void signal_out_of_memory(size_t request, const char* whence) const;
+
+ void check_for_overflow(size_t request, const char* whence) const {
+ if (UINTPTR_MAX - request < (uintptr_t)_hwm) {
+ signal_out_of_memory(request, whence);
+ }
+ }
+
public:
Arena();
Arena(size_t init_size);
@@ -220,6 +229,7 @@ protected:
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
x = ARENA_ALIGN(x);
debug_only(if (UseMallocOnly) return malloc(x);)
+ check_for_overflow(x, "Arena::Amalloc");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x);
@@ -233,6 +243,7 @@ protected:
void *Amalloc_4(size_t x) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
debug_only(if (UseMallocOnly) return malloc(x);)
+ check_for_overflow(x, "Arena::Amalloc_4");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x);
@@ -253,6 +264,7 @@ protected:
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
x += delta;
#endif
+ check_for_overflow(x, "Arena::Amalloc_D");
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x); // grow() returns a result aligned >= 8 bytes.
diff --git a/src/share/vm/utilities/globalDefinitions_gcc.hpp b/src/share/vm/utilities/globalDefinitions_gcc.hpp
index 77454680f..cc244b4a7 100644
--- a/src/share/vm/utilities/globalDefinitions_gcc.hpp
+++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp
@@ -77,6 +77,7 @@
# endif
#ifdef LINUX
+#define __STDC_LIMIT_MACROS
#include <inttypes.h>
#include <signal.h>
#include <ucontext.h>
diff --git a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
index 93d92b61d..e11fa58fa 100644
--- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
+++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
@@ -148,6 +148,17 @@ typedef unsigned int uintptr_t;
#endif
#endif
+// On solaris 8, UINTPTR_MAX is defined as empty.
+// Everywhere else it's an actual value.
+#if UINTPTR_MAX - 1 == -1
+#undef UINTPTR_MAX
+#ifdef _LP64
+#define UINTPTR_MAX UINT64_MAX
+#else
+#define UINTPTR_MAX UINT32_MAX
+#endif /* ifdef _LP64 */
+#endif
+
// Additional Java basic types
typedef unsigned char jubyte;
diff --git a/src/share/vm/utilities/globalDefinitions_visCPP.hpp b/src/share/vm/utilities/globalDefinitions_visCPP.hpp
index 0deb70ab6..2d6d7daf8 100644
--- a/src/share/vm/utilities/globalDefinitions_visCPP.hpp
+++ b/src/share/vm/utilities/globalDefinitions_visCPP.hpp
@@ -41,6 +41,7 @@
# include <stdio.h> // for va_list
# include <time.h>
# include <fcntl.h>
+# include <limits.h>
// Need this on windows to get the math constants (e.g., M_PI).
#define _USE_MATH_DEFINES
# include <math.h>
@@ -99,6 +100,14 @@ typedef signed int intptr_t;
typedef signed int ssize_t;
#endif
+#ifndef UINTPTR_MAX
+#ifdef _WIN64
+#define UINTPTR_MAX _UI64_MAX
+#else
+#define UINTPTR_MAX _UI32_MAX
+#endif
+#endif
+
//----------------------------------------------------------------------------------------------------
// Additional Java basic types
diff --git a/test/runtime/6878713/Test6878713.sh b/test/runtime/6878713/Test6878713.sh
new file mode 100644
index 000000000..54b011468
--- /dev/null
+++ b/test/runtime/6878713/Test6878713.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+##
+## @test
+## @bug 6878713
+## @summary Verifier heap corruption, relating to backward jsrs
+## @run shell/timeout=120 Test6878713.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+ PARENT=`dirname \`which java\``
+ TESTJAVA=`dirname ${PARENT}`
+ echo "TESTJAVA not set, selecting " ${TESTJAVA}
+ echo "If this is incorrect, try setting the variable manually."
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+BIT_FLAG=""
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ SunOS | Linux )
+ NULL=/dev/null
+ PS=":"
+ FS="/"
+ ## for solaris, linux it's HOME
+ FILE_LOCATION=$HOME
+ if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
+ then
+ BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT | grep -v '^#'`
+ fi
+ ;;
+ Windows_* )
+ NULL=NUL
+ PS=";"
+ FS="\\"
+ ;;
+ * )
+ echo "Unrecognized system!"
+ exit 1;
+ ;;
+esac
+
+JEMMYPATH=${CPAPPEND}
+CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
+
+THIS_DIR=`pwd`
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
+
+${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} OOMCrashClass1960_2 > test.out 2>&1
+
+if [ -s core -o -s "hs_*.log" ]
+then
+ cat hs*.log
+ echo "Test Failed"
+ exit 1
+else
+ echo "Test Passed"
+ exit 0
+fi
diff --git a/test/runtime/6878713/testcase.jar b/test/runtime/6878713/testcase.jar
new file mode 100644
index 000000000..b7001cf3d
--- /dev/null
+++ b/test/runtime/6878713/testcase.jar
Binary files differ