Skip to content

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:

  1. Compile-time detection: The compiler replaces unsafe function calls with safe equivalents when it can prove the buffer size at compile time.

  2. 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.

  3. 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

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:

gcc -D_FORTIFY_SOURCE=2 -O2 -o myapp myapp.c

CMake Example

add_compile_definitions(_FORTIFY_SOURCE=3)
add_compile_options(-O2)

Meson Example

add_project_arguments('-D_FORTIFY_SOURCE=3', '-O2', language: 'c')

Detection

This rule analyzes DWARF debug information to determine the FORTIFY_SOURCE level. It looks for:

  • _FORTIFY_SOURCE macro 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

References