[LeakSanitizer] valid pointer re-used after huge realloc()
Author: skrahCreated May 31, 2020Updated Sep 14, 2026
In the standalone leak sanitizer a valid pointer is re-used after a deliberate realloc() failure:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
char *ptr = malloc(1000000);
if (ptr == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(1);
}
ptr[0] = 'a';
char *a = realloc(ptr, 842105263157894744ULL);
if (a != NULL) { /* allocation is supposed to fail */
fprintf(stderr, "error: huge allocation unexpectedly worked\n");
exit(1);
}
/*
* At this point a==NULL. The original pointer is still valid according
* to the C standard!
*/
/* new allocation */
char *b = malloc(1000000);
if (b == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(1);
}
b[0] = 'b';
if (ptr[0] == 'b') { /* The new allocation re-used the valid ptr! */
fprintf(stderr, "error: pointer handed out twice!\n");
exit(1);
}
free(b);
free(ptr);
return 0;
}Standalone leak sanitizer fails:
$ export LSAN_OPTIONS="allocator_may_return_null=1"
$ /home/stefan/clang/bin/clang -Wall -Wextra -fsanitize=leak -o realloc realloc.c
$ ./realloc
==24104==WARNING: LeakSanitizer failed to allocate 0xbafc24672035e58 bytes
error: pointer handed out twice!The integrated leak sanitizer appears to work:
$ export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=1"
$ /home/stefan/clang/bin/clang -Wall -Wextra -fsanitize=address,leak -o realloc realloc.c
$ ./realloc
==24114==WARNING: AddressSanitizer failed to allocate 0xbafc24672035e58 bytesFor good measure, Valgrind is happy, too:
$ /home/stefan/clang/bin/clang -Wall -Wextra -o realloc realloc.c
$ valgrind ./realloc
==24123== Memcheck, a memory error detector
==24123== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==24123== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==24123== Command: ./realloc
==24123==
==24123==
==24123== HEAP SUMMARY:
==24123== in use at exit: 0 bytes in 0 blocks
==24123== total heap usage: 3 allocs, 3 frees, 842,105,263,159,894,744 bytes allocated
==24123==
==24123== All heap blocks were freed -- no leaks are possible
==24123==
==24123== For counts of detected and suppressed errors, rerun with: -v
==24123== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)I hope I didn't forget some linker option, but I reproduced this with several gcc and clang versions.
Source: google/sanitizers