Skip to content

Commit 96912ae

Browse files
committed
[TySan] A Type Sanitizer (Clang)
1 parent eb97b07 commit 96912ae

File tree

16 files changed

+116
-30
lines changed

16 files changed

+116
-30
lines changed

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ FEATURE(nullability_nullable_result, true)
9999
FEATURE(memory_sanitizer,
100100
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
101101
SanitizerKind::KernelMemory))
102+
FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type))
102103
FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
103104
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
104105
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))

clang/include/clang/Basic/Sanitizers.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ SANITIZER("fuzzer", Fuzzer)
7373
// libFuzzer-required instrumentation, no linking.
7474
SANITIZER("fuzzer-no-link", FuzzerNoLink)
7575

76+
// TypeSanitizer
77+
SANITIZER("type", Type)
78+
7679
// ThreadSanitizer
7780
SANITIZER("thread", Thread)
7881

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class SanitizerArgs {
8686
bool needsHwasanAliasesRt() const {
8787
return needsHwasanRt() && HwasanUseAliases;
8888
}
89+
bool needsTysanRt() const { return Sanitizers.has(SanitizerKind::Type); }
8990
bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
9091
bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
9192
bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
8181
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
8282
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
83+
#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"
8384
#include "llvm/Transforms/ObjCARC.h"
8485
#include "llvm/Transforms/Scalar/EarlyCSE.h"
8586
#include "llvm/Transforms/Scalar/GVN.h"
@@ -697,6 +698,11 @@ static void addSanitizers(const Triple &TargetTriple,
697698
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
698699
}
699700

701+
if (LangOpts.Sanitize.has(SanitizerKind::Type)) {
702+
MPM.addPass(ModuleTypeSanitizerPass());
703+
MPM.addPass(createModuleToFunctionPassAdaptor(TypeSanitizerPass()));
704+
}
705+
700706
auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
701707
if (LangOpts.Sanitize.has(Mask)) {
702708
bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
482482
LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment);
483483
CGM.setStaticLocalDeclAddress(&D, castedAddr);
484484

485-
CGM.getSanitizerMetadata()->reportGlobal(var, D);
485+
CGM.getSanitizerMetadata()->reportGlobalToASan(var, D);
486+
CGM.getSanitizerMetadata()->reportGlobalToTySan(var, D);
486487

487488
// Emit global variable debug descriptor for static vars.
488489
CGDebugInfo *DI = getDebugInfo();

clang/lib/CodeGen/CGDeclCXX.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
472472
!isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))
473473
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
474474

475+
if (getLangOpts().Sanitize.has(SanitizerKind::Type) &&
476+
!isInNoSanitizeList(SanitizerKind::Type, Fn, Loc))
477+
Fn->addFnAttr(llvm::Attribute::SanitizeType);
478+
475479
if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
476480
!isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc))
477481
Fn->addFnAttr(llvm::Attribute::SanitizeThread);

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
806806
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
807807
if (SanOpts.has(SanitizerKind::Thread))
808808
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
809+
if (SanOpts.has(SanitizerKind::Type))
810+
Fn->addFnAttr(llvm::Attribute::SanitizeType);
809811
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
810812
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
811813
}

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
396396
if (LangOpts.HLSL)
397397
createHLSLRuntime();
398398

399-
// Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
400-
if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
399+
// Enable TBAA unless it's suppressed. TSan and TySan need TBAA even at O0.
400+
if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Thread | SanitizerKind::Type) ||
401401
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
402402
TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts,
403403
getLangOpts(), getCXXABI().getMangleContext()));
@@ -4982,7 +4982,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
49824982
}
49834983

49844984
if (D)
4985-
SanitizerMD->reportGlobal(GV, *D);
4985+
SanitizerMD->reportGlobalToASan(GV, *D);
49864986

49874987
LangAS ExpectedAS =
49884988
D ? D->getType().getAddressSpace()
@@ -5523,7 +5523,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
55235523
if (NeedsGlobalCtor || NeedsGlobalDtor)
55245524
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
55255525

5526-
SanitizerMD->reportGlobal(GV, *D, NeedsGlobalCtor);
5526+
SanitizerMD->reportGlobalToASan(GV, *D, NeedsGlobalCtor);
5527+
SanitizerMD->reportGlobalToTySan(GV, *D);
55275528

55285529
// Emit global variable debug information.
55295530
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -6400,7 +6401,8 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
64006401
if (Entry)
64016402
*Entry = GV;
64026403

6403-
SanitizerMD->reportGlobal(GV, S->getStrTokenLoc(0), "<string literal>");
6404+
SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>");
6405+
// FIXME: Should we also report to the TySan?
64046406

64056407
return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV),
64066408
GV->getValueType(), Alignment);

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
227227
}
228228

229229
llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
230-
// At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
231-
if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
230+
// At -O0 or relaxed aliasing, TBAA is not emitted for regular types (unless
231+
// we're running TypeSanitizer).
232+
if (!Features.Sanitize.has(SanitizerKind::Type) &&
233+
(CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
232234
return nullptr;
233235

234236
// If the type has the may_alias attribute (even on a typedef), it is

clang/lib/CodeGen/SanitizerMetadata.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
3434
return Mask;
3535
}
3636

37-
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
38-
SourceLocation Loc, StringRef Name,
39-
QualType Ty,
40-
SanitizerMask NoSanitizeAttrMask,
41-
bool IsDynInit) {
37+
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
38+
SourceLocation Loc, StringRef Name,
39+
QualType Ty,
40+
SanitizerMask NoSanitizeAttrMask,
41+
bool IsDynInit) {
4242
SanitizerSet FsanitizeArgument = CGM.getLangOpts().Sanitize;
4343
if (!isAsanHwasanOrMemTag(FsanitizeArgument))
4444
return;
@@ -75,8 +75,8 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
7575
GV->setSanitizerMetadata(Meta);
7676
}
7777

78-
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
79-
bool IsDynInit) {
78+
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
79+
const VarDecl &D, bool IsDynInit) {
8080
if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
8181
return;
8282
std::string QualName;
@@ -94,10 +94,34 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
9494
return NoSanitizeMask;
9595
};
9696

97-
reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), getNoSanitizeMask(D),
98-
IsDynInit);
97+
reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(),
98+
getNoSanitizeMask(D), IsDynInit);
99+
}
100+
101+
void SanitizerMetadata::reportGlobalToTySan(llvm::GlobalVariable *GV,
102+
const VarDecl &D) {
103+
if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Type))
104+
return;
105+
106+
for (auto Attr : D.specific_attrs<NoSanitizeAttr>())
107+
if (Attr->getMask() & SanitizerKind::Type)
108+
return;
109+
110+
QualType QTy = D.getType();
111+
llvm::MDNode *TBAAInfo = CGM.getTBAATypeInfo(QTy);
112+
if (!TBAAInfo || TBAAInfo == CGM.getTBAATypeInfo(CGM.getContext().CharTy))
113+
return;
114+
115+
llvm::Metadata *GlobalMetadata[] = {llvm::ConstantAsMetadata::get(GV),
116+
TBAAInfo};
117+
118+
llvm::MDNode *ThisGlobal =
119+
llvm::MDNode::get(CGM.getLLVMContext(), GlobalMetadata);
120+
llvm::NamedMDNode *TysanGlobals =
121+
CGM.getModule().getOrInsertNamedMetadata("llvm.tysan.globals");
122+
TysanGlobals->addOperand(ThisGlobal);
99123
}
100124

101125
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
102-
reportGlobal(GV, SourceLocation(), "", QualType(), SanitizerKind::All);
126+
reportGlobalToASan(GV, SourceLocation(), "", QualType(), SanitizerKind::All);
103127
}

0 commit comments

Comments
 (0)