[BOLT] Gadget scanner: implement finer-grained --scanners=... argument (#176135)
Add separate options to enable each of the available gadget detectors. Furthermore, add two meta-options enabling all PtrAuth scanners and all available scanners of any type (which is only PtrAuth for now, though). This commit renames `pacret` option to `ptrauth-pac-ret` and `pauth` to `ptrauth-all`.
This commit is contained in:
parent
d87ac5bf3e
commit
481da949a4
@ -13,6 +13,7 @@
|
||||
#include "bolt/Core/BinaryFunction.h"
|
||||
#include "bolt/Core/MCInstUtils.h"
|
||||
#include "bolt/Passes/BinaryPasses.h"
|
||||
#include "bolt/Utils/CommandLineOpts.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <memory>
|
||||
|
||||
@ -161,7 +162,8 @@ class FunctionAnalysisContext {
|
||||
MCPlusBuilder::AllocatorIdTy AllocatorId;
|
||||
FunctionAnalysisResult Result;
|
||||
|
||||
bool PacRetGadgetsOnly;
|
||||
/// Bitmask of detectors to run (only GS_PTRAUTH_* are allowed).
|
||||
opts::GadgetKindBitmask EnabledDetectors;
|
||||
|
||||
void findUnsafeUses(SmallVector<PartialReport<MCPhysReg>> &Reports);
|
||||
void augmentUnsafeUseReports(ArrayRef<PartialReport<MCPhysReg>> Reports);
|
||||
@ -176,9 +178,7 @@ class FunctionAnalysisContext {
|
||||
public:
|
||||
FunctionAnalysisContext(BinaryFunction &BF,
|
||||
MCPlusBuilder::AllocatorIdTy AllocatorId,
|
||||
bool PacRetGadgetsOnly)
|
||||
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
|
||||
PacRetGadgetsOnly(PacRetGadgetsOnly) {}
|
||||
opts::GadgetKindBitmask EnabledDetectors);
|
||||
|
||||
void run();
|
||||
|
||||
@ -186,8 +186,8 @@ public:
|
||||
};
|
||||
|
||||
class Analysis : public BinaryFunctionPass {
|
||||
/// Only search for pac-ret violations.
|
||||
bool PacRetGadgetsOnly;
|
||||
/// Bitmask of detectors to run (only GS_PTRAUTH_* are allowed).
|
||||
opts::GadgetKindBitmask EnabledDetectors;
|
||||
|
||||
void runOnFunction(BinaryFunction &Function,
|
||||
MCPlusBuilder::AllocatorIdTy AllocatorId);
|
||||
@ -196,8 +196,7 @@ class Analysis : public BinaryFunctionPass {
|
||||
std::mutex AnalysisResultsMutex;
|
||||
|
||||
public:
|
||||
explicit Analysis(bool PacRetGadgetsOnly)
|
||||
: BinaryFunctionPass(false), PacRetGadgetsOnly(PacRetGadgetsOnly) {}
|
||||
explicit Analysis(opts::GadgetKindBitmask EnabledDetectors);
|
||||
|
||||
const char *getName() const override { return "pauth-gadget-scanner"; }
|
||||
|
||||
|
||||
@ -130,9 +130,27 @@ bool processAllFunctions();
|
||||
/// Return true if we should dump dot graphs for the given function.
|
||||
bool shouldDumpDot(const llvm::bolt::BinaryFunction &Function);
|
||||
|
||||
enum GadgetScannerKind { GS_PACRET, GS_PAUTH, GS_ALL };
|
||||
/// Bitmask representing a subset of possible gadget kinds.
|
||||
enum GadgetKindBitmask : unsigned {
|
||||
/// Scan for unprotected backward control-flow (return instructions).
|
||||
GS_PTRAUTH_RETURN_TARGETS = (1 << 0),
|
||||
/// Scan for tail calls performed with untrusted link register.
|
||||
GS_PTRAUTH_TAIL_CALLS = (1 << 1),
|
||||
/// Scan for unprotected forward control-flow (branch and call instructions).
|
||||
GS_PTRAUTH_BRANCH_AND_CALL_TARGETS = (1 << 2),
|
||||
/// Scan for signing oracles.
|
||||
GS_PTRAUTH_SIGN_ORACLES = (1 << 3),
|
||||
/// Scan for authentication oracles.
|
||||
GS_PTRAUTH_AUTH_ORACLES = (1 << 4),
|
||||
|
||||
extern llvm::cl::bits<GadgetScannerKind> GadgetScannersToRun;
|
||||
/// Scan for all Pointer Authentication issues.
|
||||
GS_PTRAUTH_ALL_MASK = GS_PTRAUTH_RETURN_TARGETS | GS_PTRAUTH_TAIL_CALLS |
|
||||
GS_PTRAUTH_BRANCH_AND_CALL_TARGETS |
|
||||
GS_PTRAUTH_SIGN_ORACLES | GS_PTRAUTH_AUTH_ORACLES,
|
||||
|
||||
/// Run all implemented scanners.
|
||||
GS_ALL_MASK = GS_PTRAUTH_ALL_MASK,
|
||||
};
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
||||
@ -1553,6 +1553,11 @@ collectRegsToTrack(ArrayRef<PartialReport<MCPhysReg>> Reports) {
|
||||
|
||||
void FunctionAnalysisContext::findUnsafeUses(
|
||||
SmallVector<PartialReport<MCPhysReg>> &Reports) {
|
||||
const auto HandledDetectors =
|
||||
opts::GS_PTRAUTH_ALL_MASK & ~opts::GS_PTRAUTH_AUTH_ORACLES;
|
||||
if (!(EnabledDetectors & HandledDetectors))
|
||||
return;
|
||||
|
||||
auto Analysis = SrcSafetyAnalysis::create(BF, AllocatorId, {});
|
||||
LLVM_DEBUG(dbgs() << "Running src register safety analysis...\n");
|
||||
Analysis->run();
|
||||
@ -1617,19 +1622,22 @@ void FunctionAnalysisContext::findUnsafeUses(
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto Report = shouldReportReturnGadget(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
|
||||
if (PacRetGadgetsOnly)
|
||||
return;
|
||||
|
||||
if (auto Report = shouldReportUnsafeTailCall(BC, BF, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
|
||||
if (auto Report = shouldReportCallGadget(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
if (auto Report = shouldReportSigningOracle(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
if (EnabledDetectors & opts::GS_PTRAUTH_RETURN_TARGETS) {
|
||||
if (auto Report = shouldReportReturnGadget(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
}
|
||||
if (EnabledDetectors & opts::GS_PTRAUTH_TAIL_CALLS) {
|
||||
if (auto Report = shouldReportUnsafeTailCall(BC, BF, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
}
|
||||
if (EnabledDetectors & opts::GS_PTRAUTH_BRANCH_AND_CALL_TARGETS) {
|
||||
if (auto Report = shouldReportCallGadget(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
}
|
||||
if (EnabledDetectors & opts::GS_PTRAUTH_SIGN_ORACLES) {
|
||||
if (auto Report = shouldReportSigningOracle(BC, Inst, S))
|
||||
Reports.push_back(*Report);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1660,8 +1668,10 @@ void FunctionAnalysisContext::augmentUnsafeUseReports(
|
||||
|
||||
void FunctionAnalysisContext::findUnsafeDefs(
|
||||
SmallVector<PartialReport<MCPhysReg>> &Reports) {
|
||||
if (PacRetGadgetsOnly)
|
||||
const auto HandledDetectors = opts::GS_PTRAUTH_AUTH_ORACLES;
|
||||
if (!(EnabledDetectors & HandledDetectors))
|
||||
return;
|
||||
|
||||
if (AuthTrapsOnFailure)
|
||||
return;
|
||||
|
||||
@ -1719,6 +1729,15 @@ void FunctionAnalysisContext::handleSimpleReports(
|
||||
llvm::erase_if(Reports, [](const auto &R) { return !R.RequestedDetails; });
|
||||
}
|
||||
|
||||
FunctionAnalysisContext::FunctionAnalysisContext(
|
||||
BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId,
|
||||
opts::GadgetKindBitmask EnabledDetectors)
|
||||
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
|
||||
EnabledDetectors(EnabledDetectors) {
|
||||
assert(!(EnabledDetectors & ~opts::GS_PTRAUTH_ALL_MASK) &&
|
||||
"Unrelated detectors requested");
|
||||
}
|
||||
|
||||
void FunctionAnalysisContext::run() {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << "Analyzing function " << BF.getPrintName()
|
||||
@ -1741,7 +1760,7 @@ void FunctionAnalysisContext::run() {
|
||||
|
||||
void Analysis::runOnFunction(BinaryFunction &BF,
|
||||
MCPlusBuilder::AllocatorIdTy AllocatorId) {
|
||||
FunctionAnalysisContext FA(BF, AllocatorId, PacRetGadgetsOnly);
|
||||
FunctionAnalysisContext FA(BF, AllocatorId, EnabledDetectors);
|
||||
FA.run();
|
||||
|
||||
const FunctionAnalysisResult &FAR = FA.getResult();
|
||||
@ -1849,6 +1868,12 @@ void GenericDiagnostic::generateReport(raw_ostream &OS,
|
||||
printBasicInfo(OS, BC, Text);
|
||||
}
|
||||
|
||||
Analysis::Analysis(opts::GadgetKindBitmask EnabledDetectors)
|
||||
: BinaryFunctionPass(false), EnabledDetectors(EnabledDetectors) {
|
||||
assert(!(EnabledDetectors & ~opts::GS_PTRAUTH_ALL_MASK) &&
|
||||
"Unrelated detectors requested");
|
||||
}
|
||||
|
||||
Error Analysis::runOnFunctions(BinaryContext &BC) {
|
||||
ParallelUtilities::WorkFuncWithAllocTy WorkFun =
|
||||
[&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId) {
|
||||
|
||||
@ -286,13 +286,23 @@ static cl::opt<bool> WriteBoltInfoSection(
|
||||
"bolt-info", cl::desc("write bolt info section in the output binary"),
|
||||
cl::init(true), cl::Hidden, cl::cat(BoltOutputCategory));
|
||||
|
||||
cl::bits<GadgetScannerKind> GadgetScannersToRun(
|
||||
"scanners", cl::desc("which gadget scanners to run"),
|
||||
static cl::list<GadgetKindBitmask> GadgetScannersToRun(
|
||||
"scanners", cl::desc("Which gadget scanners to run"),
|
||||
cl::values(
|
||||
clEnumValN(GS_PACRET, "pacret",
|
||||
"pac-ret: return address protection (subset of \"pauth\")"),
|
||||
clEnumValN(GS_PAUTH, "pauth", "All Pointer Authentication scanners"),
|
||||
clEnumValN(GS_ALL, "all", "All implemented scanners")),
|
||||
clEnumValN(GS_PTRAUTH_RETURN_TARGETS, "ptrauth-pac-ret",
|
||||
"Unprotected returns (pac-ret)"),
|
||||
clEnumValN(GS_PTRAUTH_TAIL_CALLS, "ptrauth-tail-calls",
|
||||
"Tail calls performed with unprotected link register"),
|
||||
clEnumValN(GS_PTRAUTH_BRANCH_AND_CALL_TARGETS, "ptrauth-forward-cf",
|
||||
"Unprotected calls and branches (forward control-flow)"),
|
||||
clEnumValN(GS_PTRAUTH_SIGN_ORACLES, "ptrauth-sign-oracles",
|
||||
"Signing of untrusted pointers (signing oracles)"),
|
||||
clEnumValN(GS_PTRAUTH_AUTH_ORACLES, "ptrauth-auth-oracles",
|
||||
"Authentication oracles"),
|
||||
|
||||
clEnumValN(GS_PTRAUTH_ALL_MASK, "ptrauth-all",
|
||||
"All Pointer Authentication scanners"),
|
||||
clEnumValN(GS_ALL_MASK, "all", "All implemented scanners")),
|
||||
cl::ZeroOrMore, cl::CommaSeparated, cl::cat(BinaryAnalysisCategory));
|
||||
|
||||
// Primary targets for hooking runtime library initialization hooking
|
||||
@ -3868,20 +3878,21 @@ void RewriteInstance::runBinaryAnalyses() {
|
||||
BinaryFunctionPassManager Manager(*BC);
|
||||
// FIXME: add a pass that warns about which functions do not have CFG,
|
||||
// and therefore, analysis is most likely to be less accurate.
|
||||
using GSK = opts::GadgetScannerKind;
|
||||
using PAuthScanner = PAuthGadgetScanner::Analysis;
|
||||
using PtrAuthScanner = PAuthGadgetScanner::Analysis;
|
||||
|
||||
// Accumulate all enabled analyses.
|
||||
decltype(~opts::GS_ALL_MASK) EnabledAnalyses = 0;
|
||||
for (auto NamedOptionSubmask : opts::GadgetScannersToRun)
|
||||
EnabledAnalyses |= NamedOptionSubmask;
|
||||
|
||||
// If no command line option was given, act as if "all" was specified.
|
||||
bool RunAll = !opts::GadgetScannersToRun.getBits() ||
|
||||
opts::GadgetScannersToRun.isSet(GSK::GS_ALL);
|
||||
if (opts::GadgetScannersToRun.empty())
|
||||
EnabledAnalyses = opts::GS_ALL_MASK;
|
||||
|
||||
if (RunAll || opts::GadgetScannersToRun.isSet(GSK::GS_PAUTH)) {
|
||||
Manager.registerPass(
|
||||
std::make_unique<PAuthScanner>(/*OnlyPacRetChecks=*/false));
|
||||
} else if (RunAll || opts::GadgetScannersToRun.isSet(GSK::GS_PACRET)) {
|
||||
Manager.registerPass(
|
||||
std::make_unique<PAuthScanner>(/*OnlyPacRetChecks=*/true));
|
||||
}
|
||||
const auto PtrAuthAnalyses = static_cast<opts::GadgetKindBitmask>(
|
||||
EnabledAnalyses & opts::GS_PTRAUTH_ALL_MASK);
|
||||
if (PtrAuthAnalyses)
|
||||
Manager.registerPass(std::make_unique<PtrAuthScanner>(PtrAuthAnalyses));
|
||||
|
||||
BC->logBOLTErrorsAndQuitOnFatal(Manager.runPasses());
|
||||
}
|
||||
|
||||
@ -34,9 +34,14 @@ HELP-EMPTY:
|
||||
HELP-NEXT: BinaryAnalysis options:
|
||||
HELP-EMPTY:
|
||||
HELP-NEXT: --auth-traps-on-failure - Assume authentication instructions always trap on failure
|
||||
HELP-NEXT: --scanners=<value> - which gadget scanners to run
|
||||
HELP-NEXT: =pacret - pac-ret: return address protection (subset of "pauth")
|
||||
HELP-NEXT: =pauth - All Pointer Authentication scanners
|
||||
HELP-NEXT: =all - All implemented scanners
|
||||
HELP-NEXT: --scanners=<value> - Which gadget scanners to run
|
||||
HELP-NEXT: =ptrauth-pac-ret - Unprotected returns (pac-ret)
|
||||
HELP-NEXT: =ptrauth-tail-calls - Tail calls performed with unprotected link register
|
||||
HELP-NEXT: =ptrauth-forward-cf - Unprotected calls and branches (forward control-flow)
|
||||
HELP-NEXT: =ptrauth-sign-oracles - Signing of untrusted pointers (signing oracles)
|
||||
HELP-NEXT: =ptrauth-auth-oracles - Authentication oracles
|
||||
HELP-NEXT: =ptrauth-all - All Pointer Authentication scanners
|
||||
HELP-NEXT: =all - All implemented scanners
|
||||
|
||||
HELP-EMPTY:
|
||||
HELP-NEXT: Generic Options:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// RUN: %clang %cflags -march=armv9.5-a+pauth-lr -mbranch-protection=pac-ret %s %p/../../Inputs/asm_main.c -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a -mbranch-protection=pac-ret %s %p/../../Inputs/asm_main.c -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
|
||||
// Verify that we can also detect gadgets across basic blocks
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe -Wl,--emit-relocs
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// -Wl,--no-relax prevents converting ADRP+ADD pairs into NOP+ADR.
|
||||
// RUN: %clang %cflags -march=armv8.3-a -Wl,--no-relax %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
// Test various patterns that should or should not be considered safe
|
||||
// materialization of PC-relative addresses.
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefix=FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-auth-oracles --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefix=FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-auth-oracles %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
// The detection of compiler-generated explicit pointer checks is tested in
|
||||
// gs-pauth-address-checks.s, for that reason only test here "dummy-load" and
|
||||
// "high-bits-notbi" checkers, as the shortest examples of checkers that are
|
||||
// detected per-instruction and per-BB.
|
||||
|
||||
// PACRET-NOT: authentication oracle found in function
|
||||
// FPAC-NOT: authentication oracle found in function
|
||||
|
||||
.text
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
// PACRET-NOT: non-protected call found in function
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-forward-cf --auth-traps-on-failure %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-forward-cf %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
// REQUIRES: asserts
|
||||
//
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret --no-threads \
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret --no-threads \
|
||||
// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret --no-threads --auth-traps-on-failure \
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret --no-threads --auth-traps-on-failure \
|
||||
// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --no-threads \
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all --no-threads \
|
||||
// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC,AUTH-ORACLES,PAUTH %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --no-threads --auth-traps-on-failure \
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all --no-threads --auth-traps-on-failure \
|
||||
// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC,PAUTH %s
|
||||
|
||||
// Check the debug output generated by PAuth gadget scanner to make sure the
|
||||
|
||||
130
bolt/test/binary-analysis/AArch64/gs-pauth-scanners.s
Normal file
130
bolt/test/binary-analysis/AArch64/gs-pauth-scanners.s
Normal file
@ -0,0 +1,130 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
|
||||
|
||||
// Select single detector:
|
||||
//
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-tail-calls %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=TAIL-CALLS-COMMON,TAIL-CALLS-NOFPAC
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-forward-cf %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=FORWARD-CF
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-sign-oracles %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=SIGN-ORACLES-COMMON,SIGN-ORACLES-NOFPAC
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-auth-oracles %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=AUTH-ORACLES-NOFPAC
|
||||
|
||||
// Select multiple options (either disjoint or not):
|
||||
//
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret,ptrauth-forward-cf %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,FORWARD-CF
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret,ptrauth-all %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,TAIL-CALLS-COMMON,TAIL-CALLS-NOFPAC,FORWARD-CF,SIGN-ORACLES-COMMON,SIGN-ORACLES-NOFPAC,AUTH-ORACLES-NOFPAC
|
||||
|
||||
// Select one of "all" options:
|
||||
//
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,TAIL-CALLS-COMMON,TAIL-CALLS-NOFPAC,FORWARD-CF,SIGN-ORACLES-COMMON,SIGN-ORACLES-NOFPAC,AUTH-ORACLES-NOFPAC
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=all %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,TAIL-CALLS-COMMON,TAIL-CALLS-NOFPAC,FORWARD-CF,SIGN-ORACLES-COMMON,SIGN-ORACLES-NOFPAC,AUTH-ORACLES-NOFPAC
|
||||
|
||||
// Implicitly select all scanners by omitting --scanners=... argument.
|
||||
//
|
||||
// RUN: llvm-bolt-binary-analysis %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,TAIL-CALLS-COMMON,TAIL-CALLS-NOFPAC,FORWARD-CF,SIGN-ORACLES-COMMON,SIGN-ORACLES-NOFPAC,AUTH-ORACLES-NOFPAC
|
||||
|
||||
// Test FPAC handling:
|
||||
//
|
||||
// RUN: llvm-bolt-binary-analysis --auth-traps-on-failure --scanners=ptrauth-all %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --implicit-check-not="found in function" \
|
||||
// RUN: --check-prefixes=PACRET,TAIL-CALLS-COMMON,FORWARD-CF,SIGN-ORACLES-COMMON
|
||||
// RUN: llvm-bolt-binary-analysis --auth-traps-on-failure --scanners=ptrauth-auth-oracles %t.exe 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefixes=NO-REPORTS
|
||||
|
||||
// NO-REPORTS-NOT: found in function
|
||||
|
||||
.text
|
||||
|
||||
.globl callee
|
||||
.type callee,@function
|
||||
callee:
|
||||
ret
|
||||
.size callee, .-callee
|
||||
|
||||
.globl bad_pacret
|
||||
.type bad_pacret,@function
|
||||
bad_pacret:
|
||||
// PACRET: GS-PAUTH: non-protected ret found in function bad_pacret
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
.size bad_pacret, .-bad_pacret
|
||||
|
||||
.globl bad_tail_call_common
|
||||
.type bad_tail_call_common,@function
|
||||
bad_tail_call_common:
|
||||
// TAIL-CALLS-COMMON: GS-PAUTH: untrusted link register found before tail call in function bad_tail_call_common
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
|
||||
ldp x29, x30, [sp], #16
|
||||
b callee
|
||||
.size bad_tail_call_common, .-bad_tail_call_common
|
||||
|
||||
.globl bad_tail_call_nofpac
|
||||
.type bad_tail_call_nofpac,@function
|
||||
bad_tail_call_nofpac:
|
||||
// TAIL-CALLS-NOFPAC: GS-PAUTH: untrusted link register found before tail call in function bad_tail_call_nofpac
|
||||
// AUTH-ORACLES-NOFPAC: GS-PAUTH: authentication oracle found in function bad_tail_call_nofpac
|
||||
paciasp
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
|
||||
ldp x29, x30, [sp], #16
|
||||
autiasp
|
||||
b callee
|
||||
.size bad_tail_call_nofpac, .-bad_tail_call_nofpac
|
||||
|
||||
.globl bad_call
|
||||
.type bad_call,@function
|
||||
bad_call:
|
||||
// FORWARD-CF: GS-PAUTH: non-protected call found in function bad_call
|
||||
br x0
|
||||
.size bad_call, .-bad_call
|
||||
|
||||
.globl bad_signing_oracle_common
|
||||
.type bad_signing_oracle_common,@function
|
||||
bad_signing_oracle_common:
|
||||
// SIGN-ORACLES-COMMON: GS-PAUTH: signing oracle found in function bad_signing_oracle_common
|
||||
pacda x0, x1
|
||||
ret
|
||||
.size bad_signing_oracle_common, .-bad_signing_oracle_common
|
||||
|
||||
.globl bad_signing_oracle_nofpac
|
||||
.type bad_signing_oracle_nofpac,@function
|
||||
bad_signing_oracle_nofpac:
|
||||
// SIGN-ORACLES-NOFPAC: GS-PAUTH: signing oracle found in function bad_signing_oracle_nofpac
|
||||
// AUTH-ORACLES-NOFPAC: GS-PAUTH: authentication oracle found in function bad_signing_oracle_nofpac
|
||||
autda x0, x1
|
||||
pacdb x0, x1
|
||||
ret
|
||||
.size bad_signing_oracle_nofpac, .-bad_signing_oracle_nofpac
|
||||
|
||||
.globl bad_auth_oracle
|
||||
.type bad_auth_oracle,@function
|
||||
bad_auth_oracle:
|
||||
// AUTH-ORACLES-NOFPAC: GS-PAUTH: authentication oracle found in function bad_auth_oracle
|
||||
autda x0, x1
|
||||
ret
|
||||
.size bad_auth_oracle, .-bad_auth_oracle
|
||||
@ -1,15 +1,12 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a+pauth-lr -Wl,--no-relax %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-sign-oracles %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-sign-oracles --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
|
||||
|
||||
// The detection of compiler-generated explicit pointer checks is tested in
|
||||
// gs-pauth-address-checks.s, for that reason only test here "dummy-load" and
|
||||
// "high-bits-notbi" checkers, as the shortest examples of checkers that are
|
||||
// detected per-instruction and per-BB.
|
||||
|
||||
// PACRET-NOT: signing oracle found in function
|
||||
|
||||
.text
|
||||
|
||||
.type sym,@function
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
// RUN: %clang %cflags -Wl,--entry=_custom_start -march=armv8.3-a %s -o %t.exe
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
|
||||
|
||||
// PACRET-NOT: untrusted link register found before tail call
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s
|
||||
|
||||
.text
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe -Wl,--emit-relocs
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
|
||||
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | FileCheck %s
|
||||
|
||||
// Test what instructions can be used to terminate the program abnormally
|
||||
// on security violation.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user