# HG changeset patch # User kamg # Date 1299071915 18000 # Node ID 4a9604cd7c5fa9e4cbe654b6b73ed3a40ff13c76 # Parent 5584e20db4817229eb5b2e1ff6c36c9a74656948 6878713: Verifier heap corruption, relating to backward jsrs Summary: Added overflow detection in arena Amalloc methods Reviewed-by: coleenp, phh diff -r 5584e20db481 -r 4a9604cd7c5f src/share/vm/memory/allocation.cpp --- a/src/share/vm/memory/allocation.cpp Wed Mar 02 09:41:26 2011 +0100 +++ b/src/share/vm/memory/allocation.cpp Wed Mar 02 08:18:35 2011 -0500 @@ -422,6 +422,9 @@ 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 @@ 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 @@ // 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 -r 5584e20db481 -r 4a9604cd7c5f src/share/vm/memory/allocation.hpp --- a/src/share/vm/memory/allocation.hpp Wed Mar 02 09:41:26 2011 +0100 +++ b/src/share/vm/memory/allocation.hpp Wed Mar 02 08:18:35 2011 -0500 @@ -207,6 +207,15 @@ 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 @@ 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 @@ 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 @@ 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 -r 5584e20db481 -r 4a9604cd7c5f src/share/vm/utilities/globalDefinitions_gcc.hpp --- a/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Mar 02 09:41:26 2011 +0100 +++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Mar 02 08:18:35 2011 -0500 @@ -77,6 +77,7 @@ # endif #ifdef LINUX +#define __STDC_LIMIT_MACROS #include #include #include diff -r 5584e20db481 -r 4a9604cd7c5f src/share/vm/utilities/globalDefinitions_sparcWorks.hpp --- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Wed Mar 02 09:41:26 2011 +0100 +++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Wed Mar 02 08:18:35 2011 -0500 @@ -148,6 +148,17 @@ #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 -r 5584e20db481 -r 4a9604cd7c5f src/share/vm/utilities/globalDefinitions_visCPP.hpp --- a/src/share/vm/utilities/globalDefinitions_visCPP.hpp Wed Mar 02 09:41:26 2011 +0100 +++ b/src/share/vm/utilities/globalDefinitions_visCPP.hpp Wed Mar 02 08:18:35 2011 -0500 @@ -41,6 +41,7 @@ # include // for va_list # include # include +# include // Need this on windows to get the math constants (e.g., M_PI). #define _USE_MATH_DEFINES # include @@ -99,6 +100,14 @@ 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 -r 5584e20db481 -r 4a9604cd7c5f test/runtime/6878713/Test6878713.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/6878713/Test6878713.sh Wed Mar 02 08:18:35 2011 -0500 @@ -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 -r 5584e20db481 -r 4a9604cd7c5f test/runtime/6878713/testcase.jar Binary file test/runtime/6878713/testcase.jar has changed