Skip to content

Commit 3b14862

Browse files
committed
[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: ClangBuiltLinux/linux#1742 Reviewed By: nickdesaulniers, MaskRay Differential Revision: https://reviews.llvm.org/D138945
1 parent 7710e0e commit 3b14862

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

llvm/lib/Transforms/Utils/ModuleUtils.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#include "llvm/IR/DerivedTypes.h"
1616
#include "llvm/IR/Function.h"
1717
#include "llvm/IR/IRBuilder.h"
18+
#include "llvm/IR/MDBuilder.h"
1819
#include "llvm/IR/Module.h"
1920
#include "llvm/Support/raw_ostream.h"
21+
#include "llvm/Support/xxhash.h"
2022
using namespace llvm;
2123

2224
#define DEBUG_TYPE "moduleutils"
@@ -112,6 +114,19 @@ void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
112114
appendToUsedList(M, "llvm.compiler.used", Values);
113115
}
114116

117+
static void setKCFIType(Module &M, Function &F, StringRef MangledType) {
118+
if (!M.getModuleFlag("kcfi"))
119+
return;
120+
// Matches CodeGenModule::CreateKCFITypeId in Clang.
121+
LLVMContext &Ctx = M.getContext();
122+
MDBuilder MDB(Ctx);
123+
F.setMetadata(
124+
LLVMContext::MD_kcfi_type,
125+
MDNode::get(Ctx, MDB.createConstant(ConstantInt::get(
126+
Type::getInt32Ty(Ctx),
127+
static_cast<uint32_t>(xxHash64(MangledType))))));
128+
}
129+
115130
FunctionCallee
116131
llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
117132
ArrayRef<Type *> InitArgTypes) {
@@ -128,6 +143,7 @@ Function *llvm::createSanitizerCtor(Module &M, StringRef CtorName) {
128143
GlobalValue::InternalLinkage, M.getDataLayout().getProgramAddressSpace(),
129144
CtorName, &M);
130145
Ctor->addFnAttr(Attribute::NoUnwind);
146+
setKCFIType(M, *Ctor, "_ZTSFvvE"); // void (*)(void)
131147
BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
132148
ReturnInst::Create(M.getContext(), CtorBB);
133149
// Ensure Ctor cannot be discarded, even if in a comdat.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
;; Test that we emit kcfi_type metadata for asan.module_ctor with KCFI.
2+
3+
; RUN: opt < %s -passes=asan -S | FileCheck %s
4+
5+
; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }
6+
7+
; CHECK: define internal void @asan.module_ctor()
8+
; CHECK-SAME: !kcfi_type
9+
10+
!llvm.module.flags = !{!0}
11+
!0 = !{i32 4, !"kcfi", i32 1}

0 commit comments

Comments
 (0)