Address Sanitizer (ASan) — detecting buffer overflows at runtime
WHAT is ASan?
It is not static analysis (it doesn't reason about your code at compile time) and not a separate VM like Valgrind. Instead the compiler injects extra check code around your loads and stores, and a runtime library replaces malloc/free.
WHY do we need it? (the problem)
C/C++ give you raw pointers with no bounds checking. This is fast but dangerous:
int a[4];
a[4] = 42; // writes 1 element past the end — undefined behaviourPlain execution often appears to work (you just smashed some adjacent memory), then crashes mysteriously 10,000 lines later. Bugs like this cause ~70% of security CVEs. We need something that fails loudly, immediately, at the exact line.
HOW it works — derive the mechanism from first principles
ASan has two cooperating pieces: the shadow memory and the redzones.
1. Shadow memory (the green/red map)
We want a quick way to ask "is address A valid?". Storing one byte of metadata per application byte would double memory. Instead ASan uses the key observation:
Application memory is aligned in 8-byte granules. Within one granule, the first k bytes are usually valid and the rest poisoned.
So one shadow byte describes 8 application bytes. The mapping is a simple affine function:
The shadow byte value encodes how many of the 8 bytes are addressable:
2. The injected check
For an N-byte access at address (assume aligned, ), the compiler turns *A = x into roughly:
shadow = *(char*)(((uintptr_t)A >> 3) + Offset); // load 1 shadow byte
if (shadow != 0 && ((A & 7) + N - 1) >= shadow) // last byte index ≥ allowed?
__asan_report_error(A); // poisoned → report & abort
*A = x; // else proceed3. Redzones around buffers
ASan's runtime makes malloc(n) actually allocate + redzones on each side, and poisons those redzone shadow bytes. The same happens for stack arrays (compiler-inserted) and globals. So a[4] lands in a red strip and the check fires.

Worked examples
Common mistakes
Connections
- Valgrind Memcheck — slower, no recompile, shadow-by-emulation instead of instrumentation
- Undefined Behaviour in C and C++ — the root cause ASan exposes
- MemorySanitizer (MSan) and UndefinedBehaviorSanitizer (UBSan) — sibling sanitizers
- Stack vs Heap Memory Layout — why redzones differ per region
- Compiler Instrumentation and -fsanitize flags
- Fuzzing (libFuzzer / AFL) — pairs with ASan to reach the buggy paths
Recall Feynman: explain to a 12-year-old
Pretend your toys must stay inside a box. ASan paints a thin red border of "do-not-touch" floor around every box. It also keeps a tiny cheat-sheet (one note per 8 floor tiles) saying which tiles are safe. Every time your robot hand reaches for the floor, it first peeks at the cheat-sheet. Step on green floor → fine. Step on red border → the robot shouts STOP and tells you exactly which toy box you reached past. That's how it catches you reaching outside your box the instant you do it, instead of later when everything's a mess.
Recall Active recall — quick self-test
- What formula maps an address to its shadow byte?
- Why does one shadow byte cover 8 application bytes?
- How does ASan detect use-after-free specifically?
- Name one overflow ASan can miss.
What compiler flag enables AddressSanitizer?
-fsanitize=address (in GCC and Clang)What is the shadow-address mapping formula in ASan?
Why does one shadow byte describe 8 application bytes?
What does a shadow value of 0 mean vs a negative value?
What is a "redzone" in ASan?
How does ASan catch use-after-free?
For an N-byte access at A, what condition triggers a report?
Name one class of OOB bug ASan can MISS.
Is ASan static or runtime detection?
Typical ASan overhead?
Why pair ASan with fuzzing?
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, C/C++ me pointer raw hote hain — koi bounds checking nahi. Tum a[4] likh do jabki array sirf 4 elements ka hai, to program crash bhi nahi karega turant; bas pados ki memory kharab kar dega aur baad me kahin random jagah phcatega. Debugging nightmare. ASan (AddressSanitizer) is dard ka solution hai: compile karte waqt -fsanitize=address lagao, aur compiler tumhare har memory access ke aas-paas chhota sa check code daal deta hai.
Idea simple hai: har buffer ke aage-piche ASan redzone (laal patti, "poisoned") laga deta hai, aur ek shadow memory rakhta hai jo batati hai konsi byte safe (green) hai aur konsi illegal (red). Mapping formula hai — yaani har 8 application bytes ke liye 1 shadow byte. Shadow value 0 matlab pura granule valid, value matlab pehli bytes valid, negative matlab pura poisoned. Jab bhi tum memory touch karte ho, ASan pehle shadow check karta hai; red mili to turant report aur crash, exact line ke saath.
Isse heap/stack/global overflow, use-after-free, double-free sab pakde jaate hain — aur woh bhi usi waqt jab galti hoti hai, baad me nahi. Lekin yaad rakho: ASan sirf un paths ke bugs pakdega jo tum actually chala rahe ho (isliye fuzzing ke saath use karo), aur bahut door wala wild pointer kisi dusre valid object me gir jaye to woh miss bhi ho sakta hai. Speed ~2x slow aur memory ~2-3x zyada — isliye ye testing/debug ka tool hai, production ka nahi. Mantra yaad rakho: "Green is GO, Red is DEAD."