forked from OSchip/llvm-project
Revert "[hwasan] Use stack safety analysis."
This reverts commit 12268fe14a
.
This commit is contained in:
parent
baa7f58973
commit
807d50100c
|
@ -314,19 +314,14 @@ static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
|
||||||
static_cast<const PassManagerBuilderWrapper &>(Builder);
|
static_cast<const PassManagerBuilderWrapper &>(Builder);
|
||||||
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
|
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
|
||||||
bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
|
bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
|
||||||
PM.add(createHWAddressSanitizerLegacyPassPass(
|
PM.add(
|
||||||
/*CompileKernel*/ false, Recover,
|
createHWAddressSanitizerLegacyPassPass(/*CompileKernel*/ false, Recover));
|
||||||
/*DisableOptimization*/ CGOpts.OptimizationLevel == 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
|
static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
|
||||||
legacy::PassManagerBase &PM) {
|
legacy::PassManagerBase &PM) {
|
||||||
const PassManagerBuilderWrapper &BuilderWrapper =
|
|
||||||
static_cast<const PassManagerBuilderWrapper &>(Builder);
|
|
||||||
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
|
|
||||||
PM.add(createHWAddressSanitizerLegacyPassPass(
|
PM.add(createHWAddressSanitizerLegacyPassPass(
|
||||||
/*CompileKernel*/ true, /*Recover*/ true,
|
/*CompileKernel*/ true, /*Recover*/ true));
|
||||||
/*DisableOptimization*/ CGOpts.OptimizationLevel == 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
|
static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
|
||||||
|
@ -1169,9 +1164,7 @@ static void addSanitizers(const Triple &TargetTriple,
|
||||||
auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
|
auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
|
||||||
if (LangOpts.Sanitize.has(Mask)) {
|
if (LangOpts.Sanitize.has(Mask)) {
|
||||||
bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
|
bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
|
||||||
MPM.addPass(HWAddressSanitizerPass(
|
MPM.addPass(HWAddressSanitizerPass(CompileKernel, Recover));
|
||||||
CompileKernel, Recover,
|
|
||||||
/*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
HWASanPass(SanitizerKind::HWAddress, false);
|
HWASanPass(SanitizerKind::HWAddress, false);
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-use-stack-safety=true -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-use-stack-safety=false -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY
|
|
||||||
|
|
||||||
// Default when optimizing, but not with O0.
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-generate-tags-with-calls -O0 %s -o - | FileCheck %s --check-prefix=NOSAFETY
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
char buf[10];
|
|
||||||
volatile char *x = buf;
|
|
||||||
*x = 0;
|
|
||||||
return buf[0];
|
|
||||||
// NOSAFETY: __hwasan_generate_tag
|
|
||||||
// SAFETY-NOT: __hwasan_generate_tag
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-use-stack-safety=true -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-use-stack-safety=false -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY
|
|
||||||
|
|
||||||
// Default when optimizing, but not with O0.
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
|
|
||||||
// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-generate-tags-with-calls -O0 %s -o - | FileCheck %s --check-prefix=NOSAFETY
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
char buf[10];
|
|
||||||
volatile char *x = buf;
|
|
||||||
*x = 0;
|
|
||||||
return buf[0];
|
|
||||||
// NOSAFETY: __hwasan_generate_tag
|
|
||||||
// SAFETY-NOT: __hwasan_generate_tag
|
|
||||||
}
|
|
|
@ -25,21 +25,17 @@ namespace llvm {
|
||||||
class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
|
class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
|
||||||
public:
|
public:
|
||||||
explicit HWAddressSanitizerPass(bool CompileKernel = false,
|
explicit HWAddressSanitizerPass(bool CompileKernel = false,
|
||||||
bool Recover = false,
|
bool Recover = false);
|
||||||
bool DisableOptimization = false);
|
|
||||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||||
static bool isRequired() { return true; }
|
static bool isRequired() { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CompileKernel;
|
bool CompileKernel;
|
||||||
bool Recover;
|
bool Recover;
|
||||||
bool DisableOptimization;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FunctionPass *
|
FunctionPass *createHWAddressSanitizerLegacyPassPass(bool CompileKernel = false,
|
||||||
createHWAddressSanitizerLegacyPassPass(bool CompileKernel = false,
|
bool Recover = false);
|
||||||
bool Recover = false,
|
|
||||||
bool DisableOptimization = false);
|
|
||||||
|
|
||||||
namespace HWASanAccessInfo {
|
namespace HWASanAccessInfo {
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Analysis/StackSafetyAnalysis.h"
|
|
||||||
#include "llvm/BinaryFormat/ELF.h"
|
#include "llvm/BinaryFormat/ELF.h"
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
|
@ -110,11 +109,6 @@ static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack",
|
||||||
cl::desc("instrument stack (allocas)"),
|
cl::desc("instrument stack (allocas)"),
|
||||||
cl::Hidden, cl::init(true));
|
cl::Hidden, cl::init(true));
|
||||||
|
|
||||||
static cl::opt<bool>
|
|
||||||
ClUseStackSafety("hwasan-use-stack-safety", cl::Hidden, cl::init(true),
|
|
||||||
cl::Hidden, cl::desc("Use Stack Safety analysis results"),
|
|
||||||
cl::Optional);
|
|
||||||
|
|
||||||
static cl::opt<bool> ClUARRetagToZero(
|
static cl::opt<bool> ClUARRetagToZero(
|
||||||
"hwasan-uar-retag-to-zero",
|
"hwasan-uar-retag-to-zero",
|
||||||
cl::desc("Clear alloca tags before returning from the function to allow "
|
cl::desc("Clear alloca tags before returning from the function to allow "
|
||||||
|
@ -222,22 +216,11 @@ bool shouldInstrumentWithCalls(const Triple &TargetTriple) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldUseStackSafetyAnalysis(const Triple &TargetTriple,
|
|
||||||
bool DisableOptimization) {
|
|
||||||
auto StackSafety = ClUseStackSafety.getNumOccurrences()
|
|
||||||
? ClUseStackSafety
|
|
||||||
: !DisableOptimization;
|
|
||||||
return shouldInstrumentStack(TargetTriple) && StackSafety;
|
|
||||||
// No one should use the option directly.
|
|
||||||
#pragma GCC poison ClUseStackSafety
|
|
||||||
}
|
|
||||||
/// An instrumentation pass implementing detection of addressability bugs
|
/// An instrumentation pass implementing detection of addressability bugs
|
||||||
/// using tagged pointers.
|
/// using tagged pointers.
|
||||||
class HWAddressSanitizer {
|
class HWAddressSanitizer {
|
||||||
public:
|
public:
|
||||||
HWAddressSanitizer(Module &M, bool CompileKernel, bool Recover,
|
HWAddressSanitizer(Module &M, bool CompileKernel, bool Recover) : M(M) {
|
||||||
const StackSafetyGlobalInfo *SSI)
|
|
||||||
: M(M), SSI(SSI) {
|
|
||||||
this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
|
this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
|
||||||
this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
|
this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
|
||||||
? ClEnableKhwasan
|
? ClEnableKhwasan
|
||||||
|
@ -246,8 +229,6 @@ public:
|
||||||
initializeModule();
|
initializeModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSSI(const StackSafetyGlobalInfo *S) { SSI = S; }
|
|
||||||
|
|
||||||
bool sanitizeFunction(Function &F);
|
bool sanitizeFunction(Function &F);
|
||||||
void initializeModule();
|
void initializeModule();
|
||||||
void createHwasanCtorComdat();
|
void createHwasanCtorComdat();
|
||||||
|
@ -300,7 +281,6 @@ public:
|
||||||
private:
|
private:
|
||||||
LLVMContext *C;
|
LLVMContext *C;
|
||||||
Module &M;
|
Module &M;
|
||||||
const StackSafetyGlobalInfo *SSI;
|
|
||||||
Triple TargetTriple;
|
Triple TargetTriple;
|
||||||
FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
|
FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
|
||||||
FunctionCallee HWAsanHandleVfork;
|
FunctionCallee HWAsanHandleVfork;
|
||||||
|
@ -371,8 +351,7 @@ public:
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
explicit HWAddressSanitizerLegacyPass(bool CompileKernel = false,
|
explicit HWAddressSanitizerLegacyPass(bool CompileKernel = false,
|
||||||
bool Recover = false,
|
bool Recover = false)
|
||||||
bool DisableOptimization = false)
|
|
||||||
: FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover) {
|
: FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover) {
|
||||||
initializeHWAddressSanitizerLegacyPassPass(
|
initializeHWAddressSanitizerLegacyPassPass(
|
||||||
*PassRegistry::getPassRegistry());
|
*PassRegistry::getPassRegistry());
|
||||||
|
@ -381,19 +360,11 @@ public:
|
||||||
StringRef getPassName() const override { return "HWAddressSanitizer"; }
|
StringRef getPassName() const override { return "HWAddressSanitizer"; }
|
||||||
|
|
||||||
bool doInitialization(Module &M) override {
|
bool doInitialization(Module &M) override {
|
||||||
HWASan = std::make_unique<HWAddressSanitizer>(M, CompileKernel, Recover,
|
HWASan = std::make_unique<HWAddressSanitizer>(M, CompileKernel, Recover);
|
||||||
/*SSI=*/nullptr);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runOnFunction(Function &F) override {
|
bool runOnFunction(Function &F) override {
|
||||||
if (shouldUseStackSafetyAnalysis(Triple(F.getParent()->getTargetTriple()),
|
|
||||||
DisableOptimization)) {
|
|
||||||
// We cannot call getAnalysis in doInitialization, that would cause a
|
|
||||||
// crash as the required analyses are not initialized yet.
|
|
||||||
HWASan->setSSI(
|
|
||||||
&getAnalysis<StackSafetyGlobalInfoWrapperPass>().getResult());
|
|
||||||
}
|
|
||||||
return HWASan->sanitizeFunction(F);
|
return HWASan->sanitizeFunction(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,16 +373,10 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
||||||
if (!DisableOptimization)
|
|
||||||
AU.addRequired<StackSafetyGlobalInfoWrapperPass>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<HWAddressSanitizer> HWASan;
|
std::unique_ptr<HWAddressSanitizer> HWASan;
|
||||||
bool CompileKernel;
|
bool CompileKernel;
|
||||||
bool Recover;
|
bool Recover;
|
||||||
bool DisableOptimization;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
@ -427,26 +392,18 @@ INITIALIZE_PASS_END(
|
||||||
"HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
|
"HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
|
||||||
false)
|
false)
|
||||||
|
|
||||||
FunctionPass *
|
FunctionPass *llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel,
|
||||||
llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel, bool Recover,
|
bool Recover) {
|
||||||
bool DisableOptimization) {
|
|
||||||
assert(!CompileKernel || Recover);
|
assert(!CompileKernel || Recover);
|
||||||
return new HWAddressSanitizerLegacyPass(CompileKernel, Recover,
|
return new HWAddressSanitizerLegacyPass(CompileKernel, Recover);
|
||||||
DisableOptimization);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover,
|
HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover)
|
||||||
bool DisableOptimization)
|
: CompileKernel(CompileKernel), Recover(Recover) {}
|
||||||
: CompileKernel(CompileKernel), Recover(Recover),
|
|
||||||
DisableOptimization(DisableOptimization) {}
|
|
||||||
|
|
||||||
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
|
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
|
||||||
ModuleAnalysisManager &MAM) {
|
ModuleAnalysisManager &MAM) {
|
||||||
const StackSafetyGlobalInfo *SSI = nullptr;
|
HWAddressSanitizer HWASan(M, CompileKernel, Recover);
|
||||||
if (shouldUseStackSafetyAnalysis(llvm::Triple(M.getTargetTriple()),
|
|
||||||
DisableOptimization))
|
|
||||||
SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
|
|
||||||
HWAddressSanitizer HWASan(M, CompileKernel, Recover, SSI);
|
|
||||||
bool Modified = false;
|
bool Modified = false;
|
||||||
for (Function &F : M)
|
for (Function &F : M)
|
||||||
Modified |= HWASan.sanitizeFunction(F);
|
Modified |= HWASan.sanitizeFunction(F);
|
||||||
|
@ -1300,9 +1257,7 @@ bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
|
||||||
// dynamic alloca instrumentation for them as well.
|
// dynamic alloca instrumentation for them as well.
|
||||||
!AI.isUsedWithInAlloca() &&
|
!AI.isUsedWithInAlloca() &&
|
||||||
// swifterror allocas are register promoted by ISel
|
// swifterror allocas are register promoted by ISel
|
||||||
!AI.isSwiftError()) &&
|
!AI.isSwiftError());
|
||||||
// safe allocas are not interesting
|
|
||||||
!(SSI && SSI->isSafe(AI));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HWAddressSanitizer::sanitizeFunction(Function &F) {
|
bool HWAddressSanitizer::sanitizeFunction(Function &F) {
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
; RUN: opt -hwasan -hwasan-use-stack-safety=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=SAFETY
|
|
||||||
; RUN: opt -hwasan -hwasan-use-stack-safety=0 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=NOSAFETY
|
|
||||||
|
|
||||||
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
|
|
||||||
target triple = "aarch64-unknown-linux-gnu"
|
|
||||||
|
|
||||||
; Check a safe alloca to ensure it does not get a tag.
|
|
||||||
define i32 @test_load(i32* %a) sanitize_hwaddress {
|
|
||||||
entry:
|
|
||||||
; NOSAFETY: call {{.*}}__hwasan_generate_tag
|
|
||||||
; SAFETY-NOT: call {{.*}}__hwasan_generate_tag
|
|
||||||
%buf.sroa.0 = alloca i8, align 4
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %buf.sroa.0)
|
|
||||||
store volatile i8 0, i8* %buf.sroa.0, align 4, !tbaa !8
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %buf.sroa.0)
|
|
||||||
ret i32 0
|
|
||||||
}
|
|
||||||
|
|
||||||
; Check a non-safe alloca to ensure it gets a tag.
|
|
||||||
define i32 @test_use(i32* %a) sanitize_hwaddress {
|
|
||||||
entry:
|
|
||||||
; NOSAFETY: call {{.*}}__hwasan_generate_tag
|
|
||||||
; SAFETY: call {{.*}}__hwasan_generate_tag
|
|
||||||
%buf.sroa.0 = alloca i8, align 4
|
|
||||||
call void @use(i8* nonnull %buf.sroa.0)
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %buf.sroa.0)
|
|
||||||
store volatile i8 0, i8* %buf.sroa.0, align 4, !tbaa !8
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %buf.sroa.0)
|
|
||||||
ret i32 0
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
|
||||||
|
|
||||||
declare void @use(i8* nocapture)
|
|
||||||
|
|
||||||
!8 = !{!9, !9, i64 0}
|
|
||||||
!9 = !{!"omnipotent char", !10, i64 0}
|
|
||||||
!10 = !{!"Simple C/C++ TBAA"}
|
|
Loading…
Reference in New Issue