llvm-project/llvm/lib/IR
Sami Tolvanen cff5bef948 KCFI sanitizer
The KCFI sanitizer, enabled with `-fsanitize=kcfi`, implements a
forward-edge control flow integrity scheme for indirect calls. It
uses a !kcfi_type metadata node to attach a type identifier for each
function and injects verification code before indirect calls.

Unlike the current CFI schemes implemented in LLVM, KCFI does not
require LTO, does not alter function references to point to a jump
table, and never breaks function address equality. KCFI is intended
to be used in low-level code, such as operating system kernels,
where the existing schemes can cause undue complications because
of the aforementioned properties. However, unlike the existing
schemes, KCFI is limited to validating only function pointers and is
not compatible with executable-only memory.

KCFI does not provide runtime support, but always traps when a
type mismatch is encountered. Users of the scheme are expected
to handle the trap. With `-fsanitize=kcfi`, Clang emits a `kcfi`
operand bundle to indirect calls, and LLVM lowers this to a
known architecture-specific sequence of instructions for each
callsite to make runtime patching easier for users who require this
functionality.

A KCFI type identifier is a 32-bit constant produced by taking the
lower half of xxHash64 from a C++ mangled typename. If a program
contains indirect calls to assembly functions, they must be
manually annotated with the expected type identifiers to prevent
errors. To make this easier, Clang generates a weak SHN_ABS
`__kcfi_typeid_<function>` symbol for each address-taken function
declaration, which can be used to annotate functions in assembly
as long as at least one C translation unit linked into the program
takes the function address. For example on AArch64, we might have
the following code:

```
.c:
  int f(void);
  int (*p)(void) = f;
  p();

.s:
  .4byte __kcfi_typeid_f
  .global f
  f:
    ...
```

Note that X86 uses a different preamble format for compatibility
with Linux kernel tooling. See the comments in
`X86AsmPrinter::emitKCFITypeId` for details.

As users of KCFI may need to locate trap locations for binary
validation and error handling, LLVM can additionally emit the
locations of traps to a `.kcfi_traps` section.

Similarly to other sanitizers, KCFI checking can be disabled for a
function with a `no_sanitize("kcfi")` function attribute.

Relands 67504c9549 with a fix for
32-bit builds.

Reviewed By: nickdesaulniers, kees, joaomoreira, MaskRay

Differential Revision: https://reviews.llvm.org/D119296
2022-08-24 22:41:38 +00:00
..
AbstractCallSite.cpp Cleanup includes: DebugInfo & CodeGen 2022-03-12 17:26:40 +01:00
AsmWriter.cpp [IR] Move support for dxil::TypedPointerType to LLVM core IR. 2022-08-04 10:41:11 -04:00
Assumptions.cpp [Attributor][OpenMP] Add assumption for non-call assembly instructions 2022-03-28 20:57:52 -05:00
AttributeImpl.h attributes: introduce allockind attr for describing allocator fn behavior 2022-05-31 10:01:17 -04:00
Attributes.cpp Don't use Optional::hasValue (NFC) 2022-06-20 11:49:10 -07:00
AutoUpgrade.cpp [IR] Use Min behavior for module flag "PIC Level" 2022-08-18 16:28:55 -07:00
BasicBlock.cpp Move BasicBlock::getTerminator definition to the header 2022-04-05 13:11:38 -07:00
BuiltinGCs.cpp [llvm] Fix comment typos (NFC) 2022-08-07 00:16:14 -07:00
CMakeLists.txt [IR] Move support for dxil::TypedPointerType to LLVM core IR. 2022-08-04 10:41:11 -04:00
Comdat.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
ConstantFold.cpp [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 11:24:15 -07:00
ConstantRange.cpp [ConstantRange] Fix sdiv() with one bit values (PR56333) 2022-07-01 15:44:59 +02:00
Constants.cpp [IR] Remove support for float binop constant expressions 2022-07-12 09:40:49 +02:00
ConstantsContext.h [IR] Remove support for insertvalue constant expression 2022-07-04 09:27:22 +02:00
Core.cpp [IR] Move support for dxil::TypedPointerType to LLVM core IR. 2022-08-04 10:41:11 -04:00
DIBuilder.cpp [DebugInfo] Add a TargetFuncName field in DISubprogram for 2022-04-15 16:38:23 -04:00
DataLayout.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
DebugInfo.cpp Use llvm::none_of (NFC) 2022-08-14 16:25:39 -07:00
DebugInfoMetadata.cpp Fix UB in DIExpression::appendOffset() 2022-08-19 09:16:59 -07:00
DebugLoc.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
DiagnosticHandler.cpp Remove unneeded cl::ZeroOrMore for cl::opt/cl::list options 2022-06-05 01:07:51 -07:00
DiagnosticInfo.cpp [misexpect] Re-implement MisExpect Diagnostics 2022-04-19 21:23:48 +00:00
DiagnosticPrinter.cpp
Dominators.cpp Cleanup includes: DebugInfo & CodeGen 2022-03-12 17:26:40 +01:00
FPEnv.cpp Remove redundant initialization of Optional (NFC) 2022-08-20 21:18:28 -07:00
Function.cpp [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 11:24:15 -07:00
GCStrategy.cpp [IR] Fixed ambiguous call to llvm::report_fatal_error 2022-07-23 16:28:18 +02:00
GVMaterializer.cpp [llvm] Use = default (NFC) 2022-02-06 22:18:35 -08:00
Globals.cpp [Globals] Treat nobuiltin fns as maybe-derefined. 2022-08-23 13:45:10 +01:00
IRBuilder.cpp [IRBuilder] Handle constexpr-bitcast for IRBuilder::CreateThreadLocalAddress 2022-08-03 11:13:49 +08:00
IRPrintingPasses.cpp
InlineAsm.cpp [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 11:24:15 -07:00
Instruction.cpp [SCCP][IR] Landing pads are not safe to remove 2022-03-14 14:59:32 +01:00
Instructions.cpp KCFI sanitizer 2022-08-24 22:41:38 +00:00
IntrinsicInst.cpp [WinEH] Apply funclet operand bundles to nounwind intrinsics that lower to function calls in the course of IR transforms 2022-07-26 17:52:43 +02:00
LLVMContext.cpp KCFI sanitizer 2022-08-24 22:41:38 +00:00
LLVMContextImpl.cpp [llvm] Use value instead of getValue (NFC) 2022-07-13 23:11:56 -07:00
LLVMContextImpl.h [clang][llvm][NFC] Change misexpect's tolerance option to be 32-bit 2022-08-17 14:38:53 +00:00
LLVMRemarkStreamer.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
LegacyPassManager.cpp [LegacyPassManager] Move structural hashing into Pass classes. NFC. 2022-03-17 09:51:12 +00:00
MDBuilder.cpp [ubsan] Using metadata instead of prologue data for function sanitizer 2022-06-27 12:09:13 -07:00
Mangler.cpp [COFF] Emit embedded -exclude-symbols: directives for hidden visibility for MinGW 2022-08-11 12:00:08 +03:00
Metadata.cpp [llvm][NFC] Refactor code to use ProfDataUtils 2022-08-03 00:09:45 +00:00
MetadataImpl.h
Module.cpp [IR] Use Min behavior for module flag "PIC Level" 2022-08-18 16:28:55 -07:00
ModuleSummaryIndex.cpp [WPD] Use new llvm.public.type.test intrinsic for potentially publicly visible classes 2022-07-26 08:01:08 -07:00
Operator.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
OptBisect.cpp ManagedStatic: remove many straightforward uses in llvm 2022-07-10 10:29:15 +02:00
Pass.cpp [LegacyPassManager] Move structural hashing into Pass classes. NFC. 2022-03-17 09:51:12 +00:00
PassInstrumentation.cpp
PassManager.cpp Revert "[PassManager] Add pretty stack entries before P->run() call." 2022-03-09 18:46:32 +00:00
PassRegistry.cpp ManagedStatic: remove many straightforward uses in llvm 2022-07-10 10:29:15 +02:00
PassTimingInfo.cpp
PrintPasses.cpp [MachineFunctionPass] Support -print-changed={,c}diff{,-quiet} 2022-08-01 12:56:15 -07:00
ProfDataUtils.cpp [llvm][ir] Add missing license to ProfDataUtils 2022-08-05 03:39:13 +00:00
ProfileSummary.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
PseudoProbe.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
ReplaceConstant.cpp [NFC] Remove unnecessary "#include"s from header files 2022-02-23 01:20:48 -08:00
SSAContext.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
SafepointIRVerifier.cpp freeze does not change the constant property 2022-06-14 19:53:26 +03:00
Statepoint.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
StructuralHash.cpp
SymbolTableListTraitsImpl.h
Type.cpp Cleanup header dependencies in LLVMCore 2022-02-02 06:54:20 +01:00
TypeFinder.cpp [IR] Support ifuncs in opaque pointer mode 2022-01-27 13:01:33 +01:00
TypedPointerType.cpp [IR] Move support for dxil::TypedPointerType to LLVM core IR. 2022-08-04 10:41:11 -04:00
Use.cpp [IR] Remove unused forward declarations (NFC) 2022-04-03 12:54:54 -07:00
User.cpp [IR] Report whether replaceUsesOfWith() changed something (NFC) 2022-05-18 11:46:28 +02:00
Value.cpp [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 11:24:15 -07:00
ValueSymbolTable.cpp
VectorBuilder.cpp [llvm] Don't use Optional::hasValue (NFC) 2022-06-25 21:42:52 -07:00
Verifier.cpp KCFI sanitizer 2022-08-24 22:41:38 +00:00