A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
When realloc moves a block to a new address, the old address is freed. Any other pointer that still references the old address is now dangling. Dereferencing it is a use-after-free. In a security context, an attacker who can control what gets allocated in the freed space can hijack program flow. This is not a theoretical concern. It is a recurring CVE pattern in network daemons, file parsers, and memory allocators.
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void) {char *buf = malloc(16);strcpy(buf, "initial data");char *alias = buf;printf("Before realloc:\n");printf(" buf = %p -> \"%s\"\n", (void *)buf, buf);printf(" alias = %p -> \"%s\"\n", (void *)alias, alias);char *tmp = realloc(buf, 256);if (tmp == NULL) {free(buf);return 1;}buf = tmp;printf("\nAfter realloc:\n");printf(" buf = %p -> \"%s\"\n", (void *)buf, buf);printf(" alias = %p -> ", (void *)alias);fflush(stdout);printf("%s\n", alias);free(buf);return 0;}
In this run, realloc happened to extend in place, so the addresses match. But alias still points to the old logical block. If realloc had moved the block, alias would point to freed memory. ASan tracks the allocation state and flags the access regardless. In production without ASan, this reads whatever the allocator placed in the freed chunk. An attacker who can trigger allocations between the realloc and the alias dereference can control what gets read.
After a realloc, every pointer that referenced the old block must be updated to the new address or set to NULL. There is no automatic mechanism for this. You must audit every reference. In codebases with many aliases to the same buffer, this is error-prone. The architectural fix is to minimize aliasing: one owner pointer, no copies.
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void) {char *buf = malloc(16);strcpy(buf, "initial data");char *tmp = realloc(buf, 256);if (tmp == NULL) {free(buf);return 1;}buf = tmp;printf("Safe access: \"%s\"\n", buf);free(buf);buf = NULL;return 0;}
One pointer. One realloc. One free. No aliases. No ambiguity. The simplicity is the security.
Vulnerability Profile
Use-after-free in a network daemon's buffer resizing logic. A stale pointer to a pre-realloc buffer was dereferenced after the block was moved, allowing remote attackers to read heap memory or achieve code execution via crafted packet sequences.
This vulnerability class is why security auditors grep for realloc in C codebases. Every call site is a potential use-after-free if aliases exist. The defense is architectural: minimize aliasing, update all references immediately, and run ASan in every test suite. Next: heap inspection, where attackers read freed memory to extract secrets.
Finish the lesson once you have worked through the material. This awards ★ 40 XP.