Skip to content

Commit

Permalink
Fix fallback aligned malloc/free
Browse files Browse the repository at this point in the history
The squash_aligned_free function was not reading back the original
pointer. Also make sure there is room for storing the original
pointer even with small alignment values.

Fixes #240
  • Loading branch information
jibsen committed Dec 10, 2018
1 parent 6a3f703 commit 9fbbce9
Showing 1 changed file with 21 additions and 16 deletions.
37 changes: 21 additions & 16 deletions squash/squash-memory.c
@@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016 The Squash Authors
/* Copyright (c) 2015-2018 The Squash Authors
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
Expand Down Expand Up @@ -102,6 +102,16 @@ squash_wrap_malloc (size_t size) {
return squash_memfns.calloc (1, size);
}

static void*
squash_align (void* ptr, size_t alignment) {
assert (alignment > 0);
size_t delta = (uintptr_t) ptr % alignment;
if (delta > 0) {
delta = alignment - delta;
}
return (void*) ((unsigned char*) ptr + delta);
}

/**
* @defgroup Memory
* @brief Low-level memory management
Expand Down Expand Up @@ -217,20 +227,13 @@ squash_aligned_alloc (size_t alignment, size_t size) {
* that then feel free to provide your own aligned_alloc
* implementation. */

const size_t ms = size + alignment + sizeof(void*);
const void* ptr = squash_memfns.malloc (ms);
const uintptr_t addr = (uintptr_t) ptr;

/* Figure out where to put the object. We want a pointer to the
real allocation to immediately precede the object (so we can
recover it later to pass to free()/ */
size_t padding = alignment - (addr % alignment);
if (padding < sizeof(void*))
padding += alignment;
assert ((padding + size) <= ms);

memcpy ((void*) (addr + padding - sizeof(void*)), &ptr, sizeof(void*));
return (void*) (addr + padding);
unsigned char* ptr = squash_memfns.malloc (alignment - 1 + sizeof(void*) + size);
if (ptr == NULL) {
return NULL;
}
unsigned char* aligned_ptr = squash_align (ptr + sizeof(void*), alignment);
memcpy (aligned_ptr - sizeof(void*), &ptr, sizeof(void*));
return (void*) aligned_ptr;
}

HEDLEY_UNREACHABLE ();
Expand All @@ -246,7 +249,9 @@ void squash_aligned_free (void* ptr) {
if (squash_memfns.aligned_free != NULL) {
squash_memfns.aligned_free (ptr);
} else if (ptr != NULL) {
squash_memfns.free ((void*) (((uintptr_t) ptr) - sizeof(void*)));
void* org_ptr = NULL;
memcpy (&org_ptr, (unsigned char*) ptr - sizeof(void*), sizeof(void*));
squash_memfns.free (org_ptr);
}
}

Expand Down

0 comments on commit 9fbbce9

Please sign in to comment.