Last active
April 8, 2026 17:16
-
-
Save hed0rah/f5c976fdc602688a0fd40288fde6d886 to your computer and use it in GitHub Desktop.
GCC security related flags reference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| GCC security related flags reference. | |
| Source material: | |
| http://security.stackexchange.com/questions/24444/what-is-the-most-hardened-set-of-options-for-gcc-compiling-c-c | |
| https://wiki.gentoo.org/wiki/Hardened_Gentoo | |
| https://wiki.debian.org/Hardening | |
| =================================================================================== | |
| GCC Security related flags and options: | |
| CFLAGS="-fPIE -fstack-protector-all -D_FORTIFY_SOURCE=2" | |
| LDFLAGS="-Wl,-z,now -Wl,-z,relro" | |
| Hardened Gentoo default flags. On GCC 14+ see also -fhardened below. | |
| -Wall -Wextra | |
| Turn on all warnings. | |
| -Wconversion -Wsign-conversion | |
| Warn on unsigned/signed conversions. | |
| -Wformat-security | |
| Warn about uses of format functions that represent possible security problems. | |
| -Werror | |
| Turns all warnings into errors. | |
| -arch x86_64 | |
| Compile for 64-bit to take max advantage of address space (important for ASLR; | |
| more virtual address space to choose from when randomising layout). | |
| -fstack-protector-strong -Wstack-protector --param ssp-buffer-size=4 | |
| Recommended middle ground (GCC 4.9+). Protects functions with local arrays, | |
| address-taken locals, or alloca -- without the blanket overhead of -all. | |
| Use -fstack-protector-all to guarantee guards on every function regardless. | |
| -Wstack-protector warns for any functions that would not get protected. | |
| -pie -fPIE | |
| Position-independent executable; required for ASLR to be effective. | |
| -ftrapv | |
| Generates traps for signed overflow via library calls (__addvsi3 etc.). | |
| NOTE: GCC's implementation is ~12x slower than baseline due to calling | |
| runtime helper functions instead of emitting inline branch instructions. | |
| Prefer: -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error | |
| which emits jo+ud2 inline (same efficient pattern as clang -ftrapv). | |
| Benchmark and disassembly comparison: | |
| https://lemire.me/blog/2020/09/23/how-expensive-is-integer-overflow-trapping-in-c/ | |
| -D_FORTIFY_SOURCE=2 -O1 | |
| Compile-time and runtime buffer overflow checks for calls to glibc functions | |
| (memcpy, strcpy, printf, etc.) where the destination size is statically known. | |
| Requires at least -O1 to be effective. =2 adds format string checks on top of =1. | |
| GCC 12+ / glibc 2.35+: -D_FORTIFY_SOURCE=3 extends coverage to dynamic sizes. | |
| -Wl,-z,relro,-z,now | |
| RELRO (read-only relocation). relro+now together is "Full RELRO": marks the | |
| GOT and other ELF sections read-only after startup, blocking GOT overwrites. | |
| Omitting now gives "Partial RELRO" (GOT still writable during execution). | |
| -fcf-protection=full | |
| Intel CET (Control-flow Enforcement Technology), GCC 8+ / Clang 7+. | |
| Enables IBT (Indirect Branch Tracking) and SHSTK (Shadow Stack) on supported | |
| CPUs (Intel Tiger Lake+, AMD Zen 3+). Hardware-enforced forward and backward | |
| edge CFI; stops ROP/JOP chains at the CPU level. | |
| -fhardened | |
| GCC 14+ composite flag. Equivalent to enabling: -fstack-protector-strong, | |
| -fstack-clash-protection, -fcf-protection=full, -D_FORTIFY_SOURCE=3, | |
| -D_GLIBCXX_ASSERTIONS, -pie -fPIE. Convenient single flag for production builds. | |
| Sanitizers (development/testing, not production): | |
| -fsanitize=address | |
| AddressSanitizer (ASan): detects heap/stack buffer overflows, use-after-free, | |
| double-free, use-after-return, and memory leaks. ~2x slowdown. | |
| -fsanitize=undefined | |
| UndefinedBehaviorSanitizer (UBSan): traps signed overflow, null dereference, | |
| misaligned access, integer truncation, and other UB at the point it occurs. | |
| -fsanitize=thread | |
| ThreadSanitizer (TSan): detects data races. ~5-15x slowdown. Cannot be used | |
| with ASan simultaneously. | |
| -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error | |
| Efficient signed overflow trapping (see -ftrapv note above). Emits jo+ud2 | |
| inline rather than calling a library function. | |
| --- | |
| If compiling on Windows, prefer Visual Studio over GCC, as some Windows | |
| protections (SEHOP, CFG) are not exposed through GCC. If GCC is required: | |
| -Wl,dynamicbase Tell linker to use ASLR protection | |
| -Wl,nxcompat Tell linker to use DEP protection | |
| >>> | |
| From https://wiki.debian.org/Hardening#Notes_on_Memory_Corruption_Mitigation_Methods | |
| User Space: | |
| ---------- | |
| Stack Protector | |
| gcc's -fstack-protector attempts to detect when a stack has been overwritten | |
| and aborts the program. Ubuntu has had this enabled by default since Edgy. | |
| Some programs do not play nice with it and can be worked around with | |
| -fno-stack-protector. Already done in sendmail. | |
| heap protection | |
| In glibc 2.5, no additional work needed. | |
| libc pointer encryption | |
| In mainline glibc, as PTR_MANGLE. | |
| gcc -D_FORTIFY_SOURCE=2 -O1 | |
| Compile-time protection against static sized buffer overflows. No known | |
| regressions or performance loss. Should be enabled system-wide. | |
| gcc -Wformat -Wformat-security | |
| Calls out simple printf format string vulnerabilities. Programs whose builds | |
| become noisy as a result should be fixed regardless. | |
| gcc -pie -fPIE | |
| Requires the executable be built with -fPIE for all linked .o files. Some | |
| performance loss from -fPIE; already true for all linked libraries via -fPIC. | |
| Already done with openssh, sendmail. | |
| ld -z relro | |
| (Or via gcc with -Wl,-z,relro) Already done with sendmail. | |
| ld -z now | |
| (Or via gcc with -Wl,-z,now). | |
| Kernel Space: | |
| ------------ | |
| non-exec memory segmentation (ExecShield) | |
| Stops execution of code in heap/stack. i386 specific (NX already does this | |
| for amd64). Some applications break in the protected layout. | |
| -fstack-protector | |
| Available for amd64 builds: config CC_STACKPROTECTOR. | |
| runtime memory allocation validation | |
| Detect double-frees in kernel space. | |
| Address Space Layout Randomization | |
| mmap: in mainline | |
| stack: in mainline | |
| vdso: in since 2.6.18 (COMPAT_VDSO disables it) | |
| heap/exec: in -mm, 2.6.24 | |
| brk: 2.6.25 | |
| Having heap/exec ASLR is a prerequisite for -pie being useful. | |
| /proc/$pid/maps protection | |
| Present in 2.6.22; requires sysctl toggle (kernel.maps_protect=1). | |
| Became non-optional in 2.6.27. | |
| /dev/mem protection | |
| Included in 2.6.25. | |
| link protections | |
| In Linux 3.6, enabled by default. | |
| https://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=800179c9b8a1e796e441674776d11cd4c05d61d7 | |
| Via sysctl: fs.protected_hardlinks and fs.protected_symlinks. | |
| From GRSecurity: protections against hardlink/symlink creation and following | |
| in world-writable directories. Solves tmp races. | |
| chroot, dmesg, fifo protections | |
| From GRSecurity patchset. | |
| References (from hardened Gentoo page): | |
| https://wiki.ubuntu.com/CompilerFlags | |
| http://people.redhat.com/drepper/nonselsec.pdf | |
| http://www.suse.de/~krahmer/no-nx.pdf | |
| http://www.phrack.org/archives/issues/58/4.txt | |
| http://www.phrack.org/archives/issues/59/9.txt | |
| http://www.coresecurity.com/files/attachments/Richarte_Stackguard_2002.pdf | |
| http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-ftrapvin gcc is not very well optimized so it may be better to use-fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-errorinsteadin this microbenchmark,
clang -ftrapvwas 3x slower whilegcc -ftrapvwas 12x slowerclang -ftrapvon x86-64 uses thejo(jump on overflow) instruction to check if an operation caused overflowgcc -ftrapvcalls a library function (likeint __addvsi3(int, int)) to do an operation and check for overflowwith the sanitizer flags, gcc will have the same behavior as clang and use the jump instruction instead
you can verify what it does with something like:
output of
gcc-10.2.0 -O2 -ftrapv0000000000001120 <fn>: 1120: 53 push %rbx 1121: 48 8b 1d b8 2e 00 00 mov 0x2eb8(%rip),%rbx # 3fe0 <n@@Base-0x4c> 1128: be 01 00 00 00 mov $0x1,%esi 112d: 8b 3b mov (%rbx),%edi 112f: e8 3c 00 00 00 callq 1170 <__addvsi3> 1134: 89 03 mov %eax,(%rbx) 1136: 5b pop %rbx 1137: c3 retqoutput of
gcc-10.2.0 -O2 -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error0000000000001100 <fn>: 1100: 48 8b 15 d9 2e 00 00 mov 0x2ed9(%rip),%rdx # 3fe0 <n@@Base-0x44> 1107: 8b 02 mov (%rdx),%eax 1109: 83 c0 01 add $0x1,%eax 110c: 70 03 jo 1111 <fn+0x11> 110e: 89 02 mov %eax,(%rdx) 1110: c3 retq 1111: 0f 0b ud2output of
clang-12 -O2 -ftrapv00000000000015d0 <fn>: 15d0: 48 8b 05 19 12 00 00 mov 0x1219(%rip),%rax # 27f0 <n@@Base-0x1034> 15d7: 8b 08 mov (%rax),%ecx 15d9: ff c1 inc %ecx 15db: 70 03 jo 15e0 <fn+0x10> 15dd: 89 08 mov %ecx,(%rax) 15df: c3 retq 15e0: 67 0f b9 00 ud1 (%eax),%eax