Skip to content

AD2036: PeEnableControlFlowIntegrity

Summary

Property Value
ID AD2036
Name PeEnableControlFlowIntegrity
Category Security
Severity Warning
Applies to PE (Windows, Clang/LLVM compiled)

Description

PE binaries compiled with Clang should enable Control Flow Integrity (CFI) to prevent control flow hijacking attacks. This rule checks for CFI-related instrumentation in non-MSVC compiled PE binaries.

How It Works

The rule examines the binary for:

  1. CFI-related symbols and metadata
  2. Type-based call validation instrumentation
  3. LTO usage (required for CFI)

Why This Matters

CFI provides the most comprehensive protection against control-flow hijacking attacks on non-MSVC Windows binaries.

CFI vs Windows CFG

Feature Microsoft CFG Clang CFI
Granularity Function-level Type-level
Precision Medium High
Compiler MSVC Clang
LTO required No Yes

Attack Prevention

Attack Type CFI Protection
Vtable hijacking ✓ Blocked
Function pointer corruption ✓ Blocked
Return-oriented programming Partial
Type confusion ✓ Blocked

CFI Check Types

-fsanitize=cfi-vcall        # Virtual calls
-fsanitize=cfi-nvcall       # Non-virtual member calls
-fsanitize=cfi-derived-cast # Derived casts
-fsanitize=cfi-unrelated-cast # Unrelated casts
-fsanitize=cfi-icall        # Indirect calls

Performance Considerations

Clang CFI has higher overhead than Microsoft CFG due to its finer-grained type checks:

CFI Mode Typical Overhead Notes
cfi-vcall 1-5% Virtual call checks
cfi-icall 2-8% All indirect calls
Full CFI 5-15% All checks combined
Microsoft CFG 1-2% Coarser but faster

Build-time impact: - Requires Link-Time Optimization (LTO) - Build times may increase 2-4x due to LTO - Binary size may increase slightly

Mitigation strategies: - Enable only the CFI modes you need - Use ThinLTO for faster builds: -flto=thin - Profile performance-critical code paths

Resolution

Enable CFI when building with Clang for Windows:

clang-cl -flto -fsanitize=cfi -fvisibility=hidden program.c

CMake Configuration

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    target_compile_options(myapp PRIVATE -flto -fsanitize=cfi -fvisibility=hidden)
    target_link_options(myapp PRIVATE -flto -fsanitize=cfi)
endif()