[llvm] 3b14862 - [ModuleUtils][KCFI] Set !kcfi_type metadata for sanitizer constructors

Sami Tolvanen via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 8 16:27:09 PST 2022


Author: Sami Tolvanen
Date: 2022-12-09T00:26:08Z
New Revision: 3b14862f0a968dc079530acbce4f2ca4aa7c1492

URL: https://github.com/llvm/llvm-project/commit/3b14862f0a968dc079530acbce4f2ca4aa7c1492
DIFF: https://github.com/llvm/llvm-project/commit/3b14862f0a968dc079530acbce4f2ca4aa7c1492.diff

LOG: [ModuleUtils][KCFI] Set !kcfi_type metadata for sanitizer constructors

Set KCFI type metadata for the sanitizer constructors to prevent
runtime failures when these functions are indirectly called in
instrumented code. This fixes a compatibility issue with KASAN and
-fsanitize=kcfi in the Linux kernel.

Link: https://github.com/ClangBuiltLinux/linux/issues/1742

Reviewed By: nickdesaulniers, MaskRay

Differential Revision: https://reviews.llvm.org/D138945

Added: 
    llvm/test/Instrumentation/AddressSanitizer/kcfi.ll

Modified: 
    llvm/lib/Transforms/Utils/ModuleUtils.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index b0f784b29fa19..1b2eb416d603b 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -15,8 +15,10 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/xxhash.h"
 using namespace llvm;
 
 #define DEBUG_TYPE "moduleutils"
@@ -112,6 +114,19 @@ void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
   appendToUsedList(M, "llvm.compiler.used", Values);
 }
 
+static void setKCFIType(Module &M, Function &F, StringRef MangledType) {
+  if (!M.getModuleFlag("kcfi"))
+    return;
+  // Matches CodeGenModule::CreateKCFITypeId in Clang.
+  LLVMContext &Ctx = M.getContext();
+  MDBuilder MDB(Ctx);
+  F.setMetadata(
+      LLVMContext::MD_kcfi_type,
+      MDNode::get(Ctx, MDB.createConstant(ConstantInt::get(
+                           Type::getInt32Ty(Ctx),
+                           static_cast<uint32_t>(xxHash64(MangledType))))));
+}
+
 FunctionCallee
 llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
                                    ArrayRef<Type *> InitArgTypes) {
@@ -128,6 +143,7 @@ Function *llvm::createSanitizerCtor(Module &M, StringRef CtorName) {
       GlobalValue::InternalLinkage, M.getDataLayout().getProgramAddressSpace(),
       CtorName, &M);
   Ctor->addFnAttr(Attribute::NoUnwind);
+  setKCFIType(M, *Ctor, "_ZTSFvvE"); // void (*)(void)
   BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
   ReturnInst::Create(M.getContext(), CtorBB);
   // Ensure Ctor cannot be discarded, even if in a comdat.

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/kcfi.ll b/llvm/test/Instrumentation/AddressSanitizer/kcfi.ll
new file mode 100644
index 0000000000000..d263cbd739048
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/kcfi.ll
@@ -0,0 +1,11 @@
+;; Test that we emit kcfi_type metadata for asan.module_ctor with KCFI.
+
+; RUN: opt < %s -passes=asan -S | FileCheck %s
+
+; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }
+
+; CHECK: define internal void @asan.module_ctor()
+; CHECK-SAME: !kcfi_type
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 4, !"kcfi", i32 1}


        


More information about the llvm-commits mailing list