Skip to content

[TySan] Add initial Type Sanitizer (LLVM) #76259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ class MemoryLocation;

/// A simple AA result that uses TBAA metadata to answer queries.
class TypeBasedAAResult : public AAResultBase {
/// True if type sanitizer is enabled. When TypeSanitizer is used, don't use
/// TBAA information for alias analysis as this might cause us to remove
/// memory accesses that we need to verify at runtime.
bool UsingTypeSanitizer;

public:
TypeBasedAAResult(bool UsingTypeSanitizer)
: UsingTypeSanitizer(UsingTypeSanitizer) {}

/// Handle invalidation events from the new pass manager.
///
/// By definition, this result is stateless and so remains valid.
Expand All @@ -52,6 +60,10 @@ class TypeBasedAAResult : public AAResultBase {

private:
bool Aliases(const MDNode *A, const MDNode *B) const;

/// Returns true if TBAA metadata should be used, that is if TBAA is enabled
/// and type sanitizer is not used.
bool shouldUseTBAA() const;
};

/// Analysis pass providing a never-invalidated alias analysis result.
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,7 @@ enum AttributeKindCodes {
ATTR_KIND_CORO_ELIDE_SAFE = 98,
ATTR_KIND_NO_EXT = 99,
ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
ATTR_KIND_SANITIZE_TYPE = 101,
};

enum ComdatSelectionKindCodes {
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ def SanitizeAddress : EnumAttr<"sanitize_address", IntersectPreserve, [FnAttr]>;
/// ThreadSanitizer is on.
def SanitizeThread : EnumAttr<"sanitize_thread", IntersectPreserve, [FnAttr]>;

/// TypeSanitizer is on.
def SanitizeType : EnumAttr<"sanitize_type", IntersectPreserve, [FnAttr]>;

/// MemorySanitizer is on.
def SanitizeMemory : EnumAttr<"sanitize_memory", IntersectPreserve, [FnAttr]>;

Expand Down Expand Up @@ -425,6 +428,7 @@ class CompatRuleStrAttr<string F, string Attr> : CompatRule<F> {

def : CompatRule<"isEqual<SanitizeAddressAttr>">;
def : CompatRule<"isEqual<SanitizeThreadAttr>">;
def : CompatRule<"isEqual<SanitizeTypeAttr>">;
def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
Expand Down
38 changes: 38 additions & 0 deletions llvm/include/llvm/Transforms/Instrumentation/TypeSanitizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===- Transforms/Instrumentation/TypeSanitizer.h - TySan Pass -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the type sanitizer pass.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_TYPESANITIZER_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_TYPESANITIZER_H

#include "llvm/IR/PassManager.h"

namespace llvm {
class Function;
class FunctionPass;
class Module;

/// A function pass for tysan instrumentation.
struct TypeSanitizerPass : public PassInfoMixin<TypeSanitizerPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
static bool isRequired() { return true; }
};

/// A module pass for tysan instrumentation.
///
/// Create ctor and init functions.
struct ModuleTypeSanitizerPass : public PassInfoMixin<ModuleTypeSanitizerPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
static bool isRequired() { return true; }
};

} // namespace llvm
#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_TYPESANITIZER_H */
18 changes: 11 additions & 7 deletions llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ static bool isStructPathTBAA(const MDNode *MD) {
AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
AAQueryInfo &AAQI, const Instruction *) {
if (!EnableTBAA)
if (!shouldUseTBAA())
return AliasResult::MayAlias;

if (Aliases(LocA.AATags.TBAA, LocB.AATags.TBAA))
Expand All @@ -388,7 +388,7 @@ AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
ModRefInfo TypeBasedAAResult::getModRefInfoMask(const MemoryLocation &Loc,
AAQueryInfo &AAQI,
bool IgnoreLocals) {
if (!EnableTBAA)
if (!shouldUseTBAA())
return ModRefInfo::ModRef;

const MDNode *M = Loc.AATags.TBAA;
Expand All @@ -406,7 +406,7 @@ ModRefInfo TypeBasedAAResult::getModRefInfoMask(const MemoryLocation &Loc,

MemoryEffects TypeBasedAAResult::getMemoryEffects(const CallBase *Call,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
if (!shouldUseTBAA())
return MemoryEffects::unknown();

// If this is an "immutable" type, the access is not observable.
Expand All @@ -426,7 +426,7 @@ MemoryEffects TypeBasedAAResult::getMemoryEffects(const Function *F) {
ModRefInfo TypeBasedAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
if (!shouldUseTBAA())
return ModRefInfo::ModRef;

if (const MDNode *L = Loc.AATags.TBAA)
Expand All @@ -440,7 +440,7 @@ ModRefInfo TypeBasedAAResult::getModRefInfo(const CallBase *Call,
ModRefInfo TypeBasedAAResult::getModRefInfo(const CallBase *Call1,
const CallBase *Call2,
AAQueryInfo &AAQI) {
if (!EnableTBAA)
if (!shouldUseTBAA())
return ModRefInfo::ModRef;

if (const MDNode *M1 = Call1->getMetadata(LLVMContext::MD_tbaa))
Expand Down Expand Up @@ -705,10 +705,14 @@ bool TypeBasedAAResult::Aliases(const MDNode *A, const MDNode *B) const {
return matchAccessTags(A, B);
}

bool TypeBasedAAResult::shouldUseTBAA() const {
return EnableTBAA && !UsingTypeSanitizer;
}

AnalysisKey TypeBasedAA::Key;

TypeBasedAAResult TypeBasedAA::run(Function &F, FunctionAnalysisManager &AM) {
return TypeBasedAAResult();
return TypeBasedAAResult(F.hasFnAttribute(Attribute::SanitizeType));
}

char TypeBasedAAWrapperPass::ID = 0;
Expand All @@ -724,7 +728,7 @@ TypeBasedAAWrapperPass::TypeBasedAAWrapperPass() : ImmutablePass(ID) {
}

bool TypeBasedAAWrapperPass::doInitialization(Module &M) {
Result.reset(new TypeBasedAAResult());
Result.reset(new TypeBasedAAResult(/*UsingTypeSanitizer=*/false));
return false;
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::SanitizeHWAddress;
case bitc::ATTR_KIND_SANITIZE_THREAD:
return Attribute::SanitizeThread;
case bitc::ATTR_KIND_SANITIZE_TYPE:
return Attribute::SanitizeType;
case bitc::ATTR_KIND_SANITIZE_MEMORY:
return Attribute::SanitizeMemory;
case bitc::ATTR_KIND_SANITIZE_NUMERICAL_STABILITY:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_SANITIZE_HWADDRESS;
case Attribute::SanitizeThread:
return bitc::ATTR_KIND_SANITIZE_THREAD;
case Attribute::SanitizeType:
return bitc::ATTR_KIND_SANITIZE_TYPE;
case Attribute::SanitizeMemory:
return bitc::ATTR_KIND_SANITIZE_MEMORY;
case Attribute::SanitizeNumericalStability:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/ShrinkWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,7 @@ bool ShrinkWrap::isShrinkWrapEnabled(const MachineFunction &MF) {
!(MF.getFunction().hasFnAttribute(Attribute::SanitizeAddress) ||
MF.getFunction().hasFnAttribute(Attribute::SanitizeThread) ||
MF.getFunction().hasFnAttribute(Attribute::SanitizeMemory) ||
MF.getFunction().hasFnAttribute(Attribute::SanitizeType) ||
MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress));
// If EnableShrinkWrap is set, it takes precedence on whatever the
// target sets. The rational is that we assume we want to test
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar/ADCE.h"
#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ MODULE_PASS("strip-nonlinetable-debuginfo", StripNonLineTableDebugInfoPass())
MODULE_PASS("trigger-crash-module", TriggerCrashModulePass())
MODULE_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
MODULE_PASS("tsan-module", ModuleThreadSanitizerPass())
MODULE_PASS("tysan-module", ModuleTypeSanitizerPass())
MODULE_PASS("verify", VerifierPass())
MODULE_PASS("view-callgraph", CallGraphViewerPass())
MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
Expand Down Expand Up @@ -480,6 +481,7 @@ FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())
FUNCTION_PASS("trigger-crash-function", TriggerCrashFunctionPass())
FUNCTION_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
FUNCTION_PASS("tsan", ThreadSanitizerPass())
FUNCTION_PASS("tysan", TypeSanitizerPass())
FUNCTION_PASS("typepromotion", TypePromotionPass(TM))
FUNCTION_PASS("unify-loop-exits", UnifyLoopExitsPass())
FUNCTION_PASS("vector-combine", VectorCombinePass())
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Instrumentation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_llvm_component_library(LLVMInstrumentation
SanitizerBinaryMetadata.cpp
ValueProfileCollector.cpp
ThreadSanitizer.cpp
TypeSanitizer.cpp
HWAddressSanitizer.cpp
RealtimeSanitizer.cpp

Expand Down
Loading
Loading