From 380d90b364465743f892f91098c1f67c2608977f Mon Sep 17 00:00:00 2001 From: Keith McGuigan Date: Wed, 2 Mar 2011 08:18:35 -0500 Subject: [PATCH] 6878713: Verifier heap corruption, relating to backward jsrs Added overflow detection in arena Amalloc methods Reviewed-by: coleenp, phh --- hotspot/src/share/vm/memory/allocation.cpp | 9 ++- hotspot/src/share/vm/memory/allocation.hpp | 12 +++ .../vm/utilities/globalDefinitions_gcc.hpp | 1 + .../globalDefinitions_sparcWorks.hpp | 11 +++ .../vm/utilities/globalDefinitions_visCPP.hpp | 9 +++ hotspot/test/runtime/6878713/Test6878713.sh | 74 ++++++++++++++++++ hotspot/test/runtime/6878713/testcase.jar | Bin 0 -> 984 bytes 7 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 hotspot/test/runtime/6878713/Test6878713.sh create mode 100644 hotspot/test/runtime/6878713/testcase.jar diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index 02197c5b684..19cb8df66d0 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/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/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp index 2c6845cd9f4..a9147083c8f 100644 --- a/hotspot/src/share/vm/memory/allocation.hpp +++ b/hotspot/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/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp index 77454680f2c..cc244b4a78d 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp @@ -77,6 +77,7 @@ # endif #ifdef LINUX +#define __STDC_LIMIT_MACROS #include #include #include diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp index 93d92b61d93..e11fa58fa90 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp +++ b/hotspot/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/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp index 0deb70ab63b..2d6d7daf853 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp @@ -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 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/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh new file mode 100644 index 00000000000..54b01146872 --- /dev/null +++ b/hotspot/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/hotspot/test/runtime/6878713/testcase.jar b/hotspot/test/runtime/6878713/testcase.jar new file mode 100644 index 0000000000000000000000000000000000000000..b7001cf3dd0abdb35489dc59ee3f7a5a87d1c3f0 GIT binary patch literal 984 zcmWIWW@Zs#;Nak3Xs=1MWk3R)3@i-3t|5-Po_=on|4uP5Ff#;rvvYt{FhP|C;M6Pv zQ~}rQ>*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`T^ zyq0{iOie4}hq$WR^Cemq&&5Tbh^tOxn40~m=wlHh*by^QUSDtqTHyl32uDPfp!z@( zDC_U<>s*vroZ+04SX^vqX=V^_q?Zh0zrDNHPb5%;;eoNv=|h|TDcJuDJ;vt2W8d1@ zI7326Scr$U?bx9ngUDlRxM#*ziqB_=*6MBDy78mt3*9x5`WZ<+*VI4Eel+jrvpLnz z@2FeEpSQ2=i?Zpkjx;IfyB}74^zx?Q6vLhO^me&U{oeiec%)B$zWwbLpY9!WQ-A+8 zOwKl@Zs)CzC^7T6=f{5r)s)OS5NMKyX3cD zYxmo&t!Kkbl5DzH+OG_W+0wmA@NAmTF&D9~=9M>N&n4ykJ32wQY_r7K)!z!U@;t0c zx0UXgUS9Tj)tUIxuIJ+3w>B2;i2q|(soK5q>!#>$m;Yvc=H9(_M(546o})3VUdvC} zd*#=)3DxV5?v?OO75CRwd*l_<`(<}WT&_XK#Ew@v8@K&3jCvh^>G$@_yWg`tf1mtD z#m#^7 z`HZ5#_&);X{{Qa@eBB|sU4MUUhKgGq6DR>!ckl22%E-Vl_cx-yjj^mN|}N12$22< G_5c8H`%*9f literal 0 HcmV?d00001