diff options
| author | Mattias Andrée <m@maandree.se> | 2026-05-08 22:29:35 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-05-08 22:29:35 +0200 |
| commit | 2d3a573977417d917c16742d8d9d8ead047d0ebc (patch) | |
| tree | caeac52856a9df0478e2bee53e5dda1f84422461 /libtest/libtest_free.c | |
| parent | Add DEFAULT_SUPPORT option and improve DEPENDENCIES (diff) | |
| download | librecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.gz librecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.bz2 librecrypt-2d3a573977417d917c16742d8d9d8ead047d0ebc.tar.xz | |
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libtest/libtest_free.c')
| -rw-r--r-- | libtest/libtest_free.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/libtest/libtest_free.c b/libtest/libtest_free.c new file mode 100644 index 0000000..398994b --- /dev/null +++ b/libtest/libtest_free.c @@ -0,0 +1,94 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +void +libtest_free(void *ptr, enum libtest_zero_check zero_checking) +{ + struct meminfo *mem; + int saved_errno = errno; + int unmap_err, memory_zeroed; + uint8_t *usable_area; + size_t i; +#ifdef WITH_BACKTRACE + static _Thread_local int inside_free = 0; +#endif + + /* free(3) can be called with NULL */ + if (!ptr) + return; + + /* Optionally print out trace */ +#ifdef WITH_BACKTRACE + if (!inside_free && getenv("PRETRACE_FREE")) { + inside_free = 1; + fprintf(stderr, "Deallocating: %p\n", ptr); + libtest_print_backtrace(stderr, "\tat ", 0u, NULL); + fflush(stderr); + inside_free = 0; + } +#endif + + /* Get the start of the allocation, which + * is where the book-keeping is located */ + mem = GET_MEMINFO(ptr); + + /* It is illegal to use free(3) on memory allocated with mmap(3)/mmap(2) */ + assert(mem->origin != FROM_MMAP_FILE); + assert(mem->origin != FROM_MMAP_ANON); + + /* Delist allocation */ + if (!libtest_kill_malloc_tracking) { + SPINLOCK(libtest_allocs_list_spinlock); + mem->prev->next = mem->next; + mem->next->prev = mem->prev; + SPINUNLOCK(libtest_allocs_list_spinlock); + } + + /* Check memory is zeroed */ + if (zero_checking && libtest_expect_zeroed && !mem->accept_leakage) { + usable_area = mem->usable_area; + memory_zeroed = 1; + for (i = 0u; i < mem->usable_alloc_size; i++) { + if (usable_area[i]) { + memory_zeroed = 0; + break; + } + } + assert(memory_zeroed); + } + + /* Optionally print out trace */ +#ifdef WITH_BACKTRACE + if (!inside_free && getenv("TRACE_MALLOC")) { + inside_free = 1; + fprintf(stderr, "Memory deallocated: %p\n (alloc-size=%zu, real-size=%zu)", + ptr, mem->requested_alloc_size, mem->real_alloc_size); + if (getenv("TRACE_FREE") && !getenv("PRETRACE_FREE")) + libtest_print_backtrace(stderr, "\tat ", 0u, NULL); + fflush(stderr); + inside_free = 0; + } +#endif + + /* Deallocate memory */ + unmap_err = libtest_real_munmap(mem, mem->real_alloc_size); + assert(!unmap_err); + + errno = saved_errno; +} + + +#else + + +CONST int +main(void) +{ + /* Tested via alloc.c */ + return 0; +} + + +#endif |
