Frontend Labs
⋯

30. Hardening: compiler flags, canaries, ASLR, _FORTIFY_SOURCE

clang -std=c17 -O2 \
      -D_FORTIFY_SOURCE=2 \
      -fstack-protector-strong \
      -fPIE -pie \
      -Wl,-z,relro,-z,now \
      -o hardened_app app.c

The linker flags above are for Linux/ELF toolchains. On macOS or Windows, use the platform's equivalent hardening options instead of copying the -Wl,-z,... part verbatim.

Flag Defense
-D_FORTIFY_SOURCE=2 Adds runtime bounds checks to memcpy/strcpy/sprintf/etc. when the compiler can determine the destination size — turns some overflows into an immediate abort instead of silent corruption
-fstack-protector-strong Inserts a random "canary" value before the return address; if a buffer overflow overwrites it, the program detects the corruption before returning and aborts
-fPIE -pie Position-independent executable — required for ASLR (address space layout randomization) to randomize the binary's own load address, not just libraries
-Wl,-z,relro,-z,now Makes the GOT (global offset table) read-only after startup, closing off a common exploit technique (GOT overwrite)

Real-world example. These are representative of the hardening options Linux distributions such as Debian, Fedora, and Ubuntu enable through their package build systems. They are not magic, but they often turn some memory-corruption bugs from "attacker gets control" into "process aborts."


Generated from real-life-c-guide.md · 8 Oct 2026 16:36