1 //===---- KCFI.cpp - Implements Kernel Control-Flow Integrity (KCFI) ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This pass implements Kernel Control-Flow Integrity (KCFI) indirect call 10 // check lowering. For each call instruction with a cfi-type attribute, it 11 // emits an arch-specific check before the call, and bundles the check and 12 // the call to prevent unintentional modifications. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineInstrBundle.h" 20 #include "llvm/CodeGen/MachineModuleInfo.h" 21 #include "llvm/CodeGen/TargetInstrInfo.h" 22 #include "llvm/CodeGen/TargetLowering.h" 23 #include "llvm/CodeGen/TargetSubtargetInfo.h" 24 #include "llvm/InitializePasses.h" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "kcfi" 29 #define KCFI_PASS_NAME "Insert KCFI indirect call checks" 30 31 STATISTIC(NumKCFIChecksAdded, "Number of indirect call checks added"); 32 33 namespace { 34 class KCFI : public MachineFunctionPass { 35 public: 36 static char ID; 37 38 KCFI() : MachineFunctionPass(ID) {} 39 40 StringRef getPassName() const override { return KCFI_PASS_NAME; } 41 bool runOnMachineFunction(MachineFunction &MF) override; 42 43 private: 44 /// Machine instruction info used throughout the class. 45 const TargetInstrInfo *TII = nullptr; 46 47 /// Target lowering for arch-specific parts. 48 const TargetLowering *TLI = nullptr; 49 50 /// Emits a KCFI check before an indirect call. 51 /// \returns true if the check was added and false otherwise. 52 bool emitCheck(MachineBasicBlock &MBB, 53 MachineBasicBlock::instr_iterator I) const; 54 }; 55 56 char KCFI::ID = 0; 57 } // end anonymous namespace 58 59 INITIALIZE_PASS(KCFI, DEBUG_TYPE, KCFI_PASS_NAME, false, false) 60 61 FunctionPass *llvm::createKCFIPass() { return new KCFI(); } 62 63 bool KCFI::emitCheck(MachineBasicBlock &MBB, 64 MachineBasicBlock::instr_iterator MBBI) const { 65 assert(TII && "Target instruction info was not initialized"); 66 assert(TLI && "Target lowering was not initialized"); 67 68 // If the call instruction is bundled, we can only emit a check safely if 69 // it's the first instruction in the bundle. 70 if (MBBI->isBundled() && !std::prev(MBBI)->isBundle()) 71 report_fatal_error("Cannot emit a KCFI check for a bundled call"); 72 73 // Emit a KCFI check for the call instruction at MBBI. The implementation 74 // must unfold memory operands if applicable. 75 MachineInstr *Check = TLI->EmitKCFICheck(MBB, MBBI, TII); 76 77 // Clear the original call's CFI type. 78 assert(MBBI->isCall() && "Unexpected instruction type"); 79 MBBI->setCFIType(*MBB.getParent(), 0); 80 81 // If not already bundled, bundle the check and the call to prevent 82 // further changes. 83 if (!MBBI->isBundled()) 84 finalizeBundle(MBB, Check->getIterator(), std::next(MBBI->getIterator())); 85 86 ++NumKCFIChecksAdded; 87 return true; 88 } 89 90 bool KCFI::runOnMachineFunction(MachineFunction &MF) { 91 const Module *M = MF.getMMI().getModule(); 92 if (!M->getModuleFlag("kcfi")) 93 return false; 94 95 const auto &SubTarget = MF.getSubtarget(); 96 TII = SubTarget.getInstrInfo(); 97 TLI = SubTarget.getTargetLowering(); 98 99 bool Changed = false; 100 for (MachineBasicBlock &MBB : MF) { 101 // Use instr_iterator because we don't want to skip bundles. 102 for (MachineBasicBlock::instr_iterator MII = MBB.instr_begin(), 103 MIE = MBB.instr_end(); 104 MII != MIE; ++MII) { 105 if (MII->isCall() && MII->getCFIType()) 106 Changed |= emitCheck(MBB, MII); 107 } 108 } 109 110 return Changed; 111 } 112