AD3051: CheckFortifySourceLevel¶
Summary¶
| Property | Value |
|---|---|
| ID | AD3051 |
| Name | CheckFortifySourceLevel |
| Category | Security |
| Severity | Note |
| Applies to | ELF (Linux/Unix) |
Description¶
This rule checks the FORTIFY_SOURCE level used when compiling the binary by analyzing DWARF debug information. FORTIFY_SOURCE is a GCC/Clang feature that adds bounds-checking to standard library functions like memcpy, strcpy, sprintf, and others.
FORTIFY_SOURCE Levels¶
| Level | Description | Compiler Support |
|---|---|---|
| 0 | Disabled (default without flag) | All |
| 1 | Compile-time checks only | GCC 4.1+, Clang 5+ |
| 2 | Compile-time + runtime stack buffer checks | GCC 4.1+, Clang 5+ |
| 3 | Level 2 + runtime heap buffer checks using __builtin_dynamic_object_size() |
GCC 12+, Clang 12+ |
Why This Matters¶
Buffer overflows remain one of the most common and exploitable vulnerability classes. FORTIFY_SOURCE provides automatic protection by:
-
Compile-time detection: The compiler replaces unsafe function calls with safe equivalents when it can prove the buffer size at compile time.
-
Runtime detection: When buffer sizes can't be determined at compile time, runtime checks are inserted that abort the program on overflow rather than allowing exploitation.
-
Dynamic object size (Level 3): GCC 12+ and Clang 12+ can use
__builtin_dynamic_object_size()to determine sizes of heap-allocated objects, extending protection beyond just stack buffers.
What Each Level Catches¶
char buf[10];
char *heap_buf = malloc(10);
// Level 1+: Caught at compile time if destination size is known
memcpy(buf, src, 20); // Compile warning/error
// Level 2+: Caught at runtime for stack buffers
void foo(size_t n) {
char buf[10];
memcpy(buf, src, n); // Runtime check: if n > 10, abort
}
// Level 3: Also caught for heap allocations
void bar(size_t n) {
char *buf = malloc(10);
memcpy(buf, src, n); // Runtime check: if n > 10, abort
}
How to Fix¶
Enable FORTIFY_SOURCE Level 3 (Recommended)¶
For GCC 12+ or Clang 12+:
# Maximum protection with level 3
gcc -D_FORTIFY_SOURCE=3 -O2 -o myapp myapp.c
clang -D_FORTIFY_SOURCE=3 -O2 -o myapp myapp.c
Note: FORTIFY_SOURCE requires optimization to be enabled (-O1 or higher). Without optimization, the feature is silently disabled.
Enable FORTIFY_SOURCE Level 2 (Fallback)¶
For older compilers that don't support level 3:
CMake Example¶
Meson Example¶
Detection¶
This rule analyzes DWARF debug information to determine the FORTIFY_SOURCE level. It looks for:
_FORTIFY_SOURCEmacro definitions in compilation unit producers- Compiler flags embedded in debug info
If the binary doesn't contain DWARF debug information, this rule cannot make a determination and reports N/A.
Compatibility¶
- GCC: Full support for all levels (level 3 requires GCC 12+)
- Clang: Full support for all levels (level 3 requires Clang 12+)
- Rust: Not applicable (Rust has its own memory safety guarantees)
Performance Impact¶
FORTIFY_SOURCE has minimal performance impact: - Level 1: Zero runtime overhead (compile-time only) - Level ⅔: ~1-2% overhead from runtime checks