1
0
mirror of https://github.com/adtools/clib2.git synced 2026-05-02 10:16:27 +00:00

If the memory debug option is active, realloc() can no longer damage the trailing guard area.

This commit is contained in:
obarthel
2023-09-09 12:54:16 +02:00
parent 96af3a1165
commit 4f3d0c981c

View File

@@ -78,7 +78,8 @@ __realloc(void *ptr, size_t size, const char * file, int line)
#endif /* UNIX_PATH_SEMANTICS */
else
{
size_t old_size;
size_t new_allocation_size UNUSED;
size_t old_allocation_size;
struct MemoryNode * mn;
BOOL reallocate;
@@ -92,8 +93,7 @@ __realloc(void *ptr, size_t size, const char * file, int line)
#ifdef __MEM_DEBUG
{
/* If we managed to find the memory allocation,
reallocate it. */
/* Quit if we failed to find the memory allocation. */
if (mn == NULL)
{
SHOWMSG("allocation not found");
@@ -101,8 +101,6 @@ __realloc(void *ptr, size_t size, const char * file, int line)
kprintf("[%s] %s:%ld:Address for realloc(0x%08lx,%ld) not known.\n",
__program_name, file, line, ptr, size);
/* Apparently, the address did not qualify for
reallocation. */
goto out;
}
}
@@ -120,31 +118,39 @@ __realloc(void *ptr, size_t size, const char * file, int line)
assert( FLAG_IS_CLEAR(mn->mn_Flags, MNF_NEVER_FREE) );
old_size = mn->mn_AllocationSize;
old_allocation_size = mn->mn_AllocationSize;
/* Don't do anything unless the size of the allocation
has really changed. */
/* If the memory debug option is enabled, just check if
* requested allocation size has changed.
*/
#if defined(__MEM_DEBUG)
{
reallocate = (old_size != size);
reallocate = (mn->mn_OriginalSize != size);
new_allocation_size = (sizeof(*mn) + MALLOC_HEAD_SIZE + size + MALLOC_TAIL_SIZE + MEM_BLOCKMASK) & ~MEM_BLOCKMASK;
}
#else
{
if (size > old_size)
/* The actual size of the allocation is affected by the
granularity and minimum allocation size used by the
operating system. */
new_allocation_size = (sizeof(*mn) + size + MEM_BLOCKMASK) & ~MEM_BLOCKMASK;
if (new_allocation_size > old_allocation_size)
{
/* Allocation size should grow. */
reallocate = TRUE;
}
else
else if (new_allocation_size < old_allocation_size)
{
/* Optimization: If the block size shrinks by less than half the
original allocation size, do not reallocate the
block and do not copy over the contents of the old
allocation. We also take into account that the
actual size of the allocation is affected by a
certain operating system imposed granularity. */
reallocate = (size < old_size && size <= old_size / 2);
block. */
reallocate = (size <= old_allocation_size / 2);
}
else
{
reallocate = FALSE;
}
}
#endif /* __MEM_DEBUG */
@@ -153,10 +159,10 @@ __realloc(void *ptr, size_t size, const char * file, int line)
{
void * new_ptr;
D(("realloc() size has changed; old=%ld, new=%ld", old_size, size));
D(("realloc() allocation size has changed; old=%ld, new=%ld", old_allocation_size, new_allocation_size));
/* We allocate the new memory chunk before we
attempt to replace the old. */
attempt to replace the old one. */
new_ptr = __malloc(size, file, line);
if (new_ptr == NULL)
{
@@ -164,9 +170,41 @@ __realloc(void *ptr, size_t size, const char * file, int line)
goto out;
}
/* Copy the contents of the old allocation to the new buffer. */
if (size > old_size)
size = old_size;
/* With memory debugging enabled, the size of the allocation made
* will use the requested and not the rounded size of the
* allocation, which can be shorter. We need to deal with this.
*/
#if defined(__MEM_DEBUG)
{
struct MemoryNode * new_mn;
new_mn = __find_memory_node(new_ptr);
if (new_mn == NULL)
{
free(new_ptr);
SHOWMSG("Could not find memory node for new allocation");
goto out;
}
/* Make sure that if the new allocation size is smaller than
* the old allocation, we only copy as much data as will fit
* into the new allocation.
*/
if (size > new_mn->mn_OriginalSize)
size = new_mn->mn_OriginalSize;
}
#else
{
/* We assume that the total size of the allocation will
* include padding. The requested size does not include
* the memory node, of course, which is why it is added
* here.
*/
if (size + sizeof(*mn) > old_allocation_size)
size = old_allocation_size - sizeof(*mn);
}
#endif /* __MEM_DEBUG */
memmove(new_ptr, ptr, size);
@@ -179,7 +217,7 @@ __realloc(void *ptr, size_t size, const char * file, int line)
else
{
D(("size didn't actually change that much (%ld -> %ld); returning memory block as is.",
old_size, size));
old_allocation_size, new_allocation_size));
/* No change in size. */
result = ptr;