1============================================== 2Control Flow Verification Tool Design Document 3============================================== 4 5.. contents:: 6 :local: 7 8Objective 9========= 10 11This document provides an overview of an external tool to verify the protection 12mechanisms implemented by Clang's *Control Flow Integrity* (CFI) schemes 13(``-fsanitize=cfi``). This tool, provided a binary or DSO, should infer whether 14indirect control flow operations are protected by CFI, and should output these 15results in a human-readable form. 16 17This tool should also be added as part of Clang's continuous integration testing 18framework, where modifications to the compiler ensure that CFI protection 19schemes are still present in the final binary. 20 21Location 22======== 23 24This tool will be present as a part of the LLVM toolchain, and will reside in 25the "/llvm/tools/llvm-cfi-verify" directory, relative to the LLVM trunk. It will 26be tested in two methods: 27 28- Unit tests to validate code sections, present in 29 "/llvm/unittests/tools/llvm-cfi-verify". 30- Integration tests, present in "/llvm/tools/clang/test/LLVMCFIVerify". These 31 integration tests are part of clang as part of a continuous integration 32 framework, ensuring updates to the compiler that reduce CFI coverage on 33 indirect control flow instructions are identified. 34 35Background 36========== 37 38This tool will continuously validate that CFI directives are properly 39implemented around all indirect control flows by analysing the output machine 40code. The analysis of machine code is important as it ensures that any bugs 41present in linker or compiler do not subvert CFI protections in the final 42shipped binary. 43 44Unprotected indirect control flow instructions will be flagged for manual 45review. These unexpected control flows may simply have not been accounted for in 46the compiler implementation of CFI (e.g. indirect jumps to facilitate switch 47statements may not be fully protected). 48 49It may be possible in the future to extend this tool to flag unnecessary CFI 50directives (e.g. CFI directives around a static call to a non-polymorphic base 51type). This type of directive has no security implications, but may present 52performance impacts. 53 54Design Ideas 55============ 56 57This tool will disassemble binaries and DSO's from their machine code format and 58analyse the disassembled machine code. The tool will inspect virtual calls and 59indirect function calls. This tool will also inspect indirect jumps, as inlined 60functions and jump tables should also be subject to CFI protections. Non-virtual 61calls (``-fsanitize=cfi-nvcall``) and cast checks (``-fsanitize=cfi-*cast*``) 62are not implemented due to a lack of information provided by the bytecode. 63 64The tool would operate by searching for indirect control flow instructions in 65the disassembly. A control flow graph would be generated from a small buffer of 66the instructions surrounding the 'target' control flow instruction. If the 67target instruction is branched-to, the fallthrough of the branch should be the 68CFI trap (on x86, this is a ``ud2`` instruction). If the target instruction is 69the fallthrough (i.e. immediately succeeds) of a conditional jump, the 70conditional jump target should be the CFI trap. If an indirect control flow 71instruction does not conform to one of these formats, the target will be noted 72as being CFI-unprotected. 73 74Note that in the second case outlined above (where the target instruction is the 75fallthrough of a conditional jump), if the target represents a vcall that takes 76arguments, these arguments may be pushed to the stack after the branch but 77before the target instruction. In these cases, a secondary 'spill graph' in 78constructed, to ensure the register argument used by the indirect jump/call is 79not spilled from the stack at any point in the interim period. If there are no 80spills that affect the target register, the target is marked as CFI-protected. 81 82Other Design Notes 83~~~~~~~~~~~~~~~~~~ 84 85Only machine code sections that are marked as executable will be subject to this 86analysis. Non-executable sections do not require analysis as any execution 87present in these sections has already violated the control flow integrity. 88 89Suitable extensions may be made at a later date to include analysis for indirect 90control flow operations across DSO boundaries. Currently, these CFI features are 91only experimental with an unstable ABI, making them unsuitable for analysis. 92 93The tool currently only supports the x86, x86_64, and AArch64 architectures. 94