[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:
Anatoly Trosinenko 2026-03-13 18:03:25 +03:00 committed by GitHub
parent d87ac5bf3e
commit 481da949a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 251 additions and 74 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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