Skip to content

Commit

Permalink
8339242: Fix overflow issues in AdlArena
Browse files Browse the repository at this point in the history
Reviewed-by: jsjolen, kbarrett
  • Loading branch information
caspernorrbin authored and pull[bot] committed Oct 2, 2024
1 parent 64368a3 commit db6ca44
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 27 deletions.
31 changes: 19 additions & 12 deletions src/hotspot/share/adlc/adlArena.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, 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
Expand Down Expand Up @@ -45,6 +45,7 @@ void* AdlReAllocateHeap(void* old_ptr, size_t size) {
}

void* AdlChunk::operator new(size_t requested_size, size_t length) throw() {
assert(requested_size <= SIZE_MAX - length, "overflow");
return AdlCHeapObj::operator new(requested_size + length);
}

Expand Down Expand Up @@ -129,28 +130,34 @@ void* AdlArena::grow( size_t x ) {
//------------------------------calloc-----------------------------------------
// Allocate zeroed storage in AdlArena
void *AdlArena::Acalloc( size_t items, size_t x ) {
assert(items <= SIZE_MAX / x, "overflow");
size_t z = items*x; // Total size needed
void *ptr = Amalloc(z); // Get space
memset( ptr, 0, z ); // Zap space
return ptr; // Return space
}

//------------------------------realloc----------------------------------------
static size_t pointer_delta(const void *left, const void *right) {
assert(left >= right, "pointer delta underflow");
return (uintptr_t)left - (uintptr_t)right;
}

// Reallocate storage in AdlArena.
void *AdlArena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) {
char *c_old = (char*)old_ptr; // Handy name
// Stupid fast special case
if( new_size <= old_size ) { // Shrink in-place
if( c_old+old_size == _hwm) // Attempt to free the excess bytes
_hwm = c_old+new_size; // Adjust hwm
return c_old;
}

// See if we can resize in-place
if( (c_old+old_size == _hwm) && // Adjusting recent thing
(c_old+new_size <= _max) ) { // Still fits where it sits
_hwm = c_old+new_size; // Adjust hwm
return c_old; // Return old pointer
// Reallocating the latest allocation?
if (c_old + old_size == _hwm) {
assert(_chunk->bottom() <= c_old, "invariant");

// Reallocate in place if it fits. Also handles shrinking
if (pointer_delta(_max, c_old) >= new_size) {
_hwm = c_old + new_size;
return c_old;
}
} else if (new_size <= old_size) { // Shrink in place
return c_old;
}

// Oops, got to relocate guts
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/adlc/adlArena.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, 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
Expand Down Expand Up @@ -105,8 +105,10 @@ class AdlArena: public AdlCHeapObj {
// Fast allocate in the arena. Common case is: pointer test + increment.
void* Amalloc(size_t x) {
#ifdef _LP64
assert(x <= SIZE_MAX - (8-1), "overflow");
x = (x + (8-1)) & ((unsigned)(-8));
#else
assert(x <= SIZE_MAX - (4-1), "overflow");
x = (x + (4-1)) & ((unsigned)(-4));
#endif
if (_hwm + x > _max) {
Expand Down
26 changes: 12 additions & 14 deletions src/hotspot/share/memory/arena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,6 @@ void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
return result;
}



// Reallocate storage in Arena.
void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) {
if (new_size == 0) {
Expand All @@ -324,21 +322,21 @@ void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFail
return Amalloc(new_size, alloc_failmode); // as with realloc(3), a null old ptr is equivalent to malloc(3)
}
char *c_old = (char*)old_ptr; // Handy name
// Stupid fast special case
if( new_size <= old_size ) { // Shrink in-place
if( c_old+old_size == _hwm) // Attempt to free the excess bytes
_hwm = c_old+new_size; // Adjust hwm
return c_old;
}

// make sure that new_size is legal
// Make sure that new_size is legal
size_t corrected_new_size = ARENA_ALIGN(new_size);

// See if we can resize in-place
if( (c_old+old_size == _hwm) && // Adjusting recent thing
(c_old+corrected_new_size <= _max) ) { // Still fits where it sits
_hwm = c_old+corrected_new_size; // Adjust hwm
return c_old; // Return old pointer
// Reallocating the latest allocation?
if (c_old + old_size == _hwm) {
assert(_chunk->bottom() <= c_old, "invariant");

// Reallocate in place if it fits. Also handles shrinking
if (pointer_delta(_max, c_old, 1) >= corrected_new_size) {
_hwm = c_old + corrected_new_size;
return c_old;
}
} else if (new_size <= old_size) { // Shrink in place
return c_old;
}

// Oops, got to relocate guts
Expand Down

0 comments on commit db6ca44

Please sign in to comment.