6878713: Verifier heap corruption, relating to backward jsrs
Added overflow detection in arena Amalloc methods Reviewed-by: coleenp, phh
This commit is contained in:
parent
97e74a3862
commit
380d90b364
@ -422,6 +422,9 @@ size_t Arena::used() const {
|
|||||||
return sum; // Return total consumed space.
|
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
|
// Grow a new Chunk
|
||||||
void* Arena::grow( size_t x ) {
|
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 *k = _chunk; // Get filled-up chunk address
|
||||||
_chunk = new (len) Chunk(len);
|
_chunk = new (len) Chunk(len);
|
||||||
|
|
||||||
if (_chunk == NULL)
|
if (_chunk == NULL) {
|
||||||
vm_exit_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
|
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
|
if (k) k->set_next(_chunk); // Append new chunk to end of linked list
|
||||||
else _first = _chunk;
|
else _first = _chunk;
|
||||||
@ -529,6 +533,7 @@ void* Arena::malloc(size_t size) {
|
|||||||
// for debugging with UseMallocOnly
|
// for debugging with UseMallocOnly
|
||||||
void* Arena::internal_malloc_4(size_t x) {
|
void* Arena::internal_malloc_4(size_t x) {
|
||||||
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
||||||
|
check_for_overflow(x, "Arena::internal_malloc_4");
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x);
|
return grow(x);
|
||||||
} else {
|
} else {
|
||||||
|
@ -207,6 +207,15 @@ protected:
|
|||||||
debug_only(void* malloc(size_t size);)
|
debug_only(void* malloc(size_t size);)
|
||||||
debug_only(void* internal_malloc_4(size_t x);)
|
debug_only(void* internal_malloc_4(size_t x);)
|
||||||
NOT_PRODUCT(void inc_bytes_allocated(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:
|
public:
|
||||||
Arena();
|
Arena();
|
||||||
Arena(size_t init_size);
|
Arena(size_t init_size);
|
||||||
@ -220,6 +229,7 @@ protected:
|
|||||||
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
|
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
|
||||||
x = ARENA_ALIGN(x);
|
x = ARENA_ALIGN(x);
|
||||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||||
|
check_for_overflow(x, "Arena::Amalloc");
|
||||||
NOT_PRODUCT(inc_bytes_allocated(x);)
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x);
|
return grow(x);
|
||||||
@ -233,6 +243,7 @@ protected:
|
|||||||
void *Amalloc_4(size_t x) {
|
void *Amalloc_4(size_t x) {
|
||||||
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
||||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||||
|
check_for_overflow(x, "Arena::Amalloc_4");
|
||||||
NOT_PRODUCT(inc_bytes_allocated(x);)
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x);
|
return grow(x);
|
||||||
@ -253,6 +264,7 @@ protected:
|
|||||||
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
|
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
|
||||||
x += delta;
|
x += delta;
|
||||||
#endif
|
#endif
|
||||||
|
check_for_overflow(x, "Arena::Amalloc_D");
|
||||||
NOT_PRODUCT(inc_bytes_allocated(x);)
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x); // grow() returns a result aligned >= 8 bytes.
|
return grow(x); // grow() returns a result aligned >= 8 bytes.
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
|
#define __STDC_LIMIT_MACROS
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
|
@ -148,6 +148,17 @@ typedef unsigned int uintptr_t;
|
|||||||
#endif
|
#endif
|
||||||
#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
|
// Additional Java basic types
|
||||||
|
|
||||||
typedef unsigned char jubyte;
|
typedef unsigned char jubyte;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
# include <stdio.h> // for va_list
|
# include <stdio.h> // for va_list
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
|
# include <limits.h>
|
||||||
// Need this on windows to get the math constants (e.g., M_PI).
|
// Need this on windows to get the math constants (e.g., M_PI).
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
@ -99,6 +100,14 @@ typedef signed int intptr_t;
|
|||||||
typedef signed int ssize_t;
|
typedef signed int ssize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef UINTPTR_MAX
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define UINTPTR_MAX _UI64_MAX
|
||||||
|
#else
|
||||||
|
#define UINTPTR_MAX _UI32_MAX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// Additional Java basic types
|
// Additional Java basic types
|
||||||
|
|
||||||
|
74
hotspot/test/runtime/6878713/Test6878713.sh
Normal file
74
hotspot/test/runtime/6878713/Test6878713.sh
Normal file
@ -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
|
BIN
hotspot/test/runtime/6878713/testcase.jar
Normal file
BIN
hotspot/test/runtime/6878713/testcase.jar
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user