~/Rev_

Memory-Safety Bug Classes in C: Indicator, Why, Fix

Each bug class reduced to the smallest snippet where it shows: why it's exploitable and the minimal fix. Built while learning fuzzing.

2026-07-26
work: Jul 2026 · medium · Product Security, C, Memory Safety, Fuzzing

Why this exists

Fuzzers find crashes; you still have to recognize the bug. I wanted every class reduced to a snippet small enough to spot in a code review, in one format: indicator → why it's vulnerable → minimal fix.


Stack buffer overflow

char buf[16];
strcpy(buf, input);              // no length check

Why: writes past buf into adjacent stack data: saved registers, the return address.
Fix:

snprintf(buf, sizeof buf, "%s", input);   // bounded, always NUL-terminated

Off-by-one / missing NUL terminator

char name[8];
strncpy(name, input, sizeof name);   // if input ≥ 8 chars, no '\0'
printf("%s", name);                  // reads past the end

Why: strncpy doesn't terminate when the source fills the buffer.
Fix: copy sizeof name - 1 and set name[sizeof name - 1] = '\0', or use snprintf.


Heap overflow

char *p = malloc(len);
memcpy(p, src, len + 1);         // one byte too many

Why: corrupts heap metadata or the neighboring chunk.
Fix: size from one source of truth; check len against the allocation.


Use-after-free

free(p);
...
p->handler();                    // p is dangling

Why: the freed chunk can be reallocated with attacker-controlled data.
Fix: free(p); p = NULL;, plus clear ownership rules.


Integer overflow → undersized allocation

size_t n = count * sizeof(struct item);   // wraps for large count
struct item *a = malloc(n);

Why: a wrapped size gives a tiny buffer, and the later writes overflow it.
Fix: check count > SIZE_MAX / sizeof(struct item) first, or use calloc(count, size).


Format string

printf(user_input);

Why: %x reads the stack; %n writes memory.
Fix: printf("%s", user_input);


Race condition

counter++;                       // read, add, write: not atomic

Why: two threads interleave and updates get lost. In security code, the same pattern becomes TOCTOU (check a file, then open it).
Fix: atomics or a mutex; for files, open first and check the opened handle (fstat).


Next

Run AFL++ against small harnesses for each class and write up what the fuzzer found versus what I'd have spotted by reading. That's the bridge to the Fuzzing 101 exercises.


Sources: Fuzzing Learning Curve (26 Jul 2026)