Control-Flow Integrity
What is Control-Flow Integrity?
Control-Flow IntegrityControl-Flow Integrity (CFI) constrains a program's indirect calls and returns to a precomputed set of legitimate targets, blocking ROP and JOP exploits that hijack control flow.
CFI was formalized by Abadi, Budiu, Erlingsson and Ligatti in 2005. The compiler builds a control-flow graph of the program, assigns each indirect call site a set of allowed targets, and instruments call/return sites with runtime checks. Practical implementations include LLVM CFI (forward edges via type-based bucket IDs), Microsoft Control Flow Guard, Linux Kernel CFI (kCFI), and hardware-assisted variants like Intel CET-IBT and Arm BTI for indirect branches plus shadow stacks for returns. CFI defeats classic ROP/JOP because the gadget chain violates legitimate edge sets. Coverage gaps in C/C++ code (large equivalence classes) and incompatible interfaces remain the main limitations.
● Examples
- 01
Microsoft Control Flow Guard rejecting a corrupted vtable indirect call in Edge.
- 02
Linux 6.x kernel CFI catching a ROP chain in a driver vulnerability.
● Frequently asked questions
What is Control-Flow Integrity?
Control-Flow Integrity (CFI) constrains a program's indirect calls and returns to a precomputed set of legitimate targets, blocking ROP and JOP exploits that hijack control flow. It belongs to the Application Security category of cybersecurity.
What does Control-Flow Integrity mean?
Control-Flow Integrity (CFI) constrains a program's indirect calls and returns to a precomputed set of legitimate targets, blocking ROP and JOP exploits that hijack control flow.
How does Control-Flow Integrity work?
CFI was formalized by Abadi, Budiu, Erlingsson and Ligatti in 2005. The compiler builds a control-flow graph of the program, assigns each indirect call site a set of allowed targets, and instruments call/return sites with runtime checks. Practical implementations include LLVM CFI (forward edges via type-based bucket IDs), Microsoft Control Flow Guard, Linux Kernel CFI (kCFI), and hardware-assisted variants like Intel CET-IBT and Arm BTI for indirect branches plus shadow stacks for returns. CFI defeats classic ROP/JOP because the gadget chain violates legitimate edge sets. Coverage gaps in C/C++ code (large equivalence classes) and incompatible interfaces remain the main limitations.
How do you defend against Control-Flow Integrity?
Defences for Control-Flow Integrity typically combine technical controls and operational practices, as detailed in the full definition above.
What are other names for Control-Flow Integrity?
Common alternative names include: CFI, Control Flow Guard, kCFI.
● Related terms
- appsec№ 1028
Shadow Stack
A shadow stack is a separate, protected stack that stores copies of return addresses so the CPU can detect tampering with the regular stack and block ROP attacks.
- appsec№ 545
Intel CET
Intel CET (Control-flow Enforcement Technology) is a CPU feature combining a hardware shadow stack and Indirect Branch Tracking (IBT) to block ROP, JOP and COP exploits.
- appsec№ 925
Return-Oriented Programming
Return-Oriented Programming (ROP) is a code-reuse exploit technique that chains short instruction sequences ending in RET to execute arbitrary computation without injecting new code.
- appsec№ 064
ASLR
Address Space Layout Randomization randomizes the memory locations of code, stacks, heaps, and libraries so attackers cannot reliably predict target addresses for exploits.
- appsec№ 303
DEP
Data Execution Prevention (also called NX or W^X) marks memory pages as non-executable so attackers cannot run shellcode injected into the stack or heap.
- appsec№ 670
Memory Safety
Memory safety is the property that a program never reads, writes, or executes memory it has not legitimately allocated, preventing entire classes of vulnerabilities.
● See also
- № 569Jump-Oriented Programming
- № 1095Stack Canary
- № 581KASLR
- № 1058SMEP / SMAP
- № 671Memory-Safe Languages
- № 953Rust Security Properties