Revert "[hwasan] Use stack safety analysis."

This reverts commit 12268fe14a.
This commit is contained in:
Florian Mayer 2021-07-19 12:08:02 +01:00
parent baa7f58973
commit 807d50100c
6 changed files with 18 additions and 146 deletions

View File

@ -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);

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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"}