8339242: Fix overflow issues in AdlArena

Reviewed-by: jsjolen, kbarrett
This commit is contained in:
Casper Norrbin 2024-09-11 08:45:59 +00:00 committed by Johan Sjölen
parent ceef161eea
commit 0b3f2e64e8
3 changed files with 34 additions and 27 deletions

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,6 +45,7 @@ void* AdlReAllocateHeap(void* old_ptr, size_t size) {
} }
void* AdlChunk::operator new(size_t requested_size, size_t length) throw() { 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); return AdlCHeapObj::operator new(requested_size + length);
} }
@ -129,6 +130,7 @@ void* AdlArena::grow( size_t x ) {
//------------------------------calloc----------------------------------------- //------------------------------calloc-----------------------------------------
// Allocate zeroed storage in AdlArena // Allocate zeroed storage in AdlArena
void *AdlArena::Acalloc( size_t items, size_t x ) { void *AdlArena::Acalloc( size_t items, size_t x ) {
assert(items <= SIZE_MAX / x, "overflow");
size_t z = items*x; // Total size needed size_t z = items*x; // Total size needed
void *ptr = Amalloc(z); // Get space void *ptr = Amalloc(z); // Get space
memset( ptr, 0, z ); // Zap space memset( ptr, 0, z ); // Zap space
@ -136,21 +138,26 @@ void *AdlArena::Acalloc( size_t items, size_t x ) {
} }
//------------------------------realloc---------------------------------------- //------------------------------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. // Reallocate storage in AdlArena.
void *AdlArena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) { void *AdlArena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) {
char *c_old = (char*)old_ptr; // Handy name 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 // Reallocating the latest allocation?
if( (c_old+old_size == _hwm) && // Adjusting recent thing if (c_old + old_size == _hwm) {
(c_old+new_size <= _max) ) { // Still fits where it sits assert(_chunk->bottom() <= c_old, "invariant");
_hwm = c_old+new_size; // Adjust hwm
return c_old; // Return old pointer // 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 // Oops, got to relocate guts

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -105,8 +105,10 @@ public:
// Fast allocate in the arena. Common case is: pointer test + increment. // Fast allocate in the arena. Common case is: pointer test + increment.
void* Amalloc(size_t x) { void* Amalloc(size_t x) {
#ifdef _LP64 #ifdef _LP64
assert(x <= SIZE_MAX - (8-1), "overflow");
x = (x + (8-1)) & ((unsigned)(-8)); x = (x + (8-1)) & ((unsigned)(-8));
#else #else
assert(x <= SIZE_MAX - (4-1), "overflow");
x = (x + (4-1)) & ((unsigned)(-4)); x = (x + (4-1)) & ((unsigned)(-4));
#endif #endif
if (_hwm + x > _max) { if (_hwm + x > _max) {

View File

@ -311,8 +311,6 @@ void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
return result; return result;
} }
// Reallocate storage in Arena. // Reallocate storage in Arena.
void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) { void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) {
if (new_size == 0) { if (new_size == 0) {
@ -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) 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 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); size_t corrected_new_size = ARENA_ALIGN(new_size);
// See if we can resize in-place // Reallocating the latest allocation?
if( (c_old+old_size == _hwm) && // Adjusting recent thing if (c_old + old_size == _hwm) {
(c_old+corrected_new_size <= _max) ) { // Still fits where it sits assert(_chunk->bottom() <= c_old, "invariant");
_hwm = c_old+corrected_new_size; // Adjust hwm
return c_old; // Return old pointer // 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 // Oops, got to relocate guts