[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)
Anatoly Trosinenko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 20 03:03:45 PDT 2025
https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/139778
>From 4266ffc763c260031b6e6a87c869cbd643c566aa Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH] [BOLT] Gadget scanner: optionally assume auth traps on
failure
On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.
This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
bolt/lib/Passes/PAuthGadgetScanner.cpp | 112 +++++++----
.../binary-analysis/AArch64/cmdline-args.test | 1 +
.../AArch64/gs-pauth-authentication-oracles.s | 6 +-
.../binary-analysis/AArch64/gs-pauth-calls.s | 5 +-
.../AArch64/gs-pauth-debug-output.s | 177 ++++++++++-------
.../AArch64/gs-pauth-jump-table.s | 6 +-
.../AArch64/gs-pauth-signing-oracles.s | 54 ++---
.../AArch64/gs-pauth-tail-calls.s | 184 +++++++++---------
8 files changed, 318 insertions(+), 227 deletions(-)
diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index bda971bcd9343..cfe86d32df798 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
#include "bolt/Passes/PAuthGadgetScanner.h"
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
namespace bolt {
namespace PAuthGadgetScanner {
+static cl::opt<bool> AuthTrapsOnFailure(
+ "auth-traps-on-failure",
+ cl::desc("Assume authentication instructions always trap on failure"),
+ cl::cat(opts::BinaryAnalysisCategory));
+
[[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef Label,
const MCInst &MI) {
dbgs() << " " << Label << ": ";
@@ -365,6 +371,34 @@ class SrcSafetyAnalysis {
return Clobbered;
}
+ std::optional<MCPhysReg> getRegMadeTrustedByChecking(const MCInst &Inst,
+ SrcState Cur) const {
+ // This functions cannot return multiple registers. This is never the case
+ // on AArch64.
+ std::optional<MCPhysReg> RegCheckedByInst =
+ BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+ if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+ return *RegCheckedByInst;
+
+ auto It = CheckerSequenceInfo.find(&Inst);
+ if (It == CheckerSequenceInfo.end())
+ return std::nullopt;
+
+ MCPhysReg RegCheckedBySequence = It->second.first;
+ const MCInst *FirstCheckerInst = It->second.second;
+
+ // FirstCheckerInst should belong to the same basic block (see the
+ // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+ // deterministically processed a few steps before this instruction.
+ const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+ // The sequence checks the register, but it should be authenticated before.
+ if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+ return std::nullopt;
+
+ return RegCheckedBySequence;
+ }
+
// Returns all registers that can be treated as if they are written by an
// authentication instruction.
SmallVector<MCPhysReg> getRegsMadeSafeToDeref(const MCInst &Point,
@@ -387,18 +421,38 @@ class SrcSafetyAnalysis {
Regs.push_back(DstAndSrc->first);
}
+ // Make sure explicit checker sequence keeps register safe-to-dereference
+ // when the register would be clobbered according to the regular rules:
+ //
+ // ; LR is safe to dereference here
+ // mov x16, x30 ; start of the sequence, LR is s-t-d right before
+ // xpaclri ; clobbers LR, LR is not safe anymore
+ // cmp x30, x16
+ // b.eq 1f ; end of the sequence: LR is marked as trusted
+ // brk 0x1234
+ // 1:
+ // ; at this point LR would be marked as trusted,
+ // ; but not safe-to-dereference
+ //
+ // or even just
+ //
+ // ; X1 is safe to dereference here
+ // ldr x0, [x1, #8]!
+ // ; X1 is trusted here, but it was clobbered due to address write-back
+ if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+ Regs.push_back(*CheckedReg);
+
return Regs;
}
// Returns all registers made trusted by this instruction.
SmallVector<MCPhysReg> getRegsMadeTrusted(const MCInst &Point,
const SrcState &Cur) const {
+ assert(!AuthTrapsOnFailure && "Use getRegsMadeSafeToDeref instead");
SmallVector<MCPhysReg> Regs;
// An authenticated pointer can be checked, or
- std::optional<MCPhysReg> CheckedReg =
- BC.MIB->getAuthCheckedReg(Point, /*MayOverwrite=*/false);
- if (CheckedReg && Cur.SafeToDerefRegs[*CheckedReg])
+ if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
Regs.push_back(*CheckedReg);
// ... a pointer can be authenticated by an instruction that always checks
@@ -409,19 +463,6 @@ class SrcSafetyAnalysis {
if (AutReg && IsChecked)
Regs.push_back(*AutReg);
- if (CheckerSequenceInfo.contains(&Point)) {
- MCPhysReg CheckedReg;
- const MCInst *FirstCheckerInst;
- std::tie(CheckedReg, FirstCheckerInst) = CheckerSequenceInfo.at(&Point);
-
- // FirstCheckerInst should belong to the same basic block (see the
- // assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
- // deterministically processed a few steps before this instruction.
- const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
- if (StateBeforeChecker.SafeToDerefRegs[CheckedReg])
- Regs.push_back(CheckedReg);
- }
-
// ... a safe address can be materialized, or
if (auto NewAddrReg = BC.MIB->getMaterializedAddressRegForPtrAuth(Point))
Regs.push_back(*NewAddrReg);
@@ -465,28 +506,11 @@ class SrcSafetyAnalysis {
BitVector Clobbered = getClobberedRegs(Point);
SmallVector<MCPhysReg> NewSafeToDerefRegs =
getRegsMadeSafeToDeref(Point, Cur);
- SmallVector<MCPhysReg> NewTrustedRegs = getRegsMadeTrusted(Point, Cur);
-
- // Ideally, being trusted is a strictly stronger property than being
- // safe-to-dereference. To simplify the computation of Next state, enforce
- // this for NewSafeToDerefRegs and NewTrustedRegs. Additionally, this
- // fixes the properly for "cumulative" register states in tricky cases
- // like the following:
- //
- // ; LR is safe to dereference here
- // mov x16, x30 ; start of the sequence, LR is s-t-d right before
- // xpaclri ; clobbers LR, LR is not safe anymore
- // cmp x30, x16
- // b.eq 1f ; end of the sequence: LR is marked as trusted
- // brk 0x1234
- // 1:
- // ; at this point LR would be marked as trusted,
- // ; but not safe-to-dereference
- //
- for (auto TrustedReg : NewTrustedRegs) {
- if (!is_contained(NewSafeToDerefRegs, TrustedReg))
- NewSafeToDerefRegs.push_back(TrustedReg);
- }
+ // If authentication instructions trap on failure, safe-to-dereference
+ // registers are always trusted.
+ SmallVector<MCPhysReg> NewTrustedRegs =
+ AuthTrapsOnFailure ? NewSafeToDerefRegs
+ : getRegsMadeTrusted(Point, Cur);
// Then, compute the state after this instruction is executed.
SrcState Next = Cur;
@@ -523,6 +547,11 @@ class SrcSafetyAnalysis {
dbgs() << ")\n";
});
+ // Being trusted is a strictly stronger property than being
+ // safe-to-dereference.
+ assert(!Next.TrustedRegs.test(Next.SafeToDerefRegs) &&
+ "SafeToDerefRegs should contain all TrustedRegs");
+
return Next;
}
@@ -1084,6 +1113,11 @@ class DataflowDstSafetyAnalysis
}
void run() override {
+ // As long as DstSafetyAnalysis is only computed to detect authentication
+ // oracles, it is a waste of time to compute it when authentication
+ // instructions are known to always trap on failure.
+ assert(!AuthTrapsOnFailure &&
+ "DstSafetyAnalysis is useless with faulting auth");
for (BinaryBasicBlock &BB : Func) {
if (auto CheckerInfo = BC.MIB->getAuthCheckedReg(BB)) {
LLVM_DEBUG({
@@ -1542,6 +1576,8 @@ void FunctionAnalysisContext::findUnsafeDefs(
SmallVector<PartialReport<MCPhysReg>> &Reports) {
if (PacRetGadgetsOnly)
return;
+ if (AuthTrapsOnFailure)
+ return;
auto Analysis = DstSafetyAnalysis::create(BF, AllocatorId, {});
LLVM_DEBUG({ dbgs() << "Running dst register safety analysis...\n"; });
diff --git a/bolt/test/binary-analysis/AArch64/cmdline-args.test b/bolt/test/binary-analysis/AArch64/cmdline-args.test
index 76f7c3ba0a1c7..27069436092b3 100644
--- a/bolt/test/binary-analysis/AArch64/cmdline-args.test
+++ b/bolt/test/binary-analysis/AArch64/cmdline-args.test
@@ -32,6 +32,7 @@ HELP-NEXT: OPTIONS:
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
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s b/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s
index b199c3056ba5b..f5d3b870244f4 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s
@@ -1,6 +1,7 @@
// 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 %t.exe 2>&1 | FileCheck %s
+// 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
// 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
@@ -8,6 +9,7 @@
// detected per-instruction and per-BB.
// PACRET-NOT: authentication oracle found in function
+// FPAC-NOT: authentication oracle found in function
.text
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s b/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s
index 5f49918c39c94..26ebe2d2436a1 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-calls.s
@@ -1,6 +1,7 @@
// 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 %t.exe 2>&1 | FileCheck %s
+// 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
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
index 75341063ab816..e99599c7463c6 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
@@ -1,10 +1,14 @@
// REQUIRES: asserts
//
// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
-// RUN: llvm-bolt-binary-analysis --scanners=pacret -no-threads \
-// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck %s
-// RUN: llvm-bolt-binary-analysis --scanners=pauth -no-threads \
-// RUN: -debug-only bolt-pauth-scanner %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,PAUTH %s
+// RUN: llvm-bolt-binary-analysis --scanners=pacret --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: -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: -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: -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
// that output is kept meaningful and to provide an overview of what happens
@@ -61,30 +65,54 @@ simple:
// CHECK-NEXT: State 1: src-state<empty>
// CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
// CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: DataflowSrcSafetyAnalysis::Confluence(
-// CHECK-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
-// CHECK-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
-// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: DataflowSrcSafetyAnalysis::Confluence(
+// NOFPAC-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
+// NOFPAC-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// NOFPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
+// FPAC-NEXT: DataflowSrcSafetyAnalysis::Confluence(
+// FPAC-NEXT: State 1: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
+// FPAC-NEXT: State 2: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: merged state: src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( autiza x0, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( blr x0, src-state<SafeToDerefRegs: W0 X0 W0_HI , TrustedRegs: W0 X0 W0_HI , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ldp x29, x30, [sp], #0x10, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( hint #29, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
+// FPAC-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
+// FPAC-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
// CHECK-NEXT: After src register safety analysis:
// CHECK-NEXT: Binary Function "simple" {
// CHECK-NEXT: Number : 1
@@ -255,53 +283,56 @@ auth_oracle:
// ...
// CHECK: End of Function "auth_oracle"
// ...
-// PAUTH: Running dst register safety analysis...
-// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state<CannotEscapeUnchecked: , Insts: >)
-// PAUTH-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
-// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
-// PAUTH-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
-// PAUTH-NEXT: After dst register safety analysis:
-// PAUTH-NEXT: Binary Function "auth_oracle" {
-// PAUTH-NEXT: Number : 4
-// PAUTH-NEXT: State : CFG constructed
+// FPAC-NOT: Running dst register safety analysis
+// FPAC-NOT: DstSafetyAnalysis::ComputeNext
+// FPAC-NOT: {{.*dst-state.*}}
+// AUTH-ORACLES: Running dst register safety analysis...
+// AUTH-ORACLES-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state<CannotEscapeUnchecked: , Insts: >)
+// AUTH-ORACLES-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
+// AUTH-ORACLES-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
+// AUTH-ORACLES-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: >)
+// AUTH-ORACLES-NEXT: After dst register safety analysis:
+// AUTH-ORACLES-NEXT: Binary Function "auth_oracle" {
+// AUTH-ORACLES-NEXT: Number : 4
+// AUTH-ORACLES-NEXT: State : CFG constructed
// ...
-// PAUTH: BB Layout : [[BB0]]
-// PAUTH-NEXT: }
-// PAUTH-NEXT: [[BB0]] (2 instructions, align : 1)
-// PAUTH-NEXT: Entry Point
-// PAUTH-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
-// PAUTH-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
-// PAUTH-EMPTY:
-// PAUTH-NEXT: DWARF CFI Instructions:
-// PAUTH-NEXT: <empty>
-// PAUTH-NEXT: End of Function "auth_oracle"
-// PAUTH-EMPTY:
-// PAUTH-NEXT: Found auth inst: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
-// PAUTH-NEXT: Authenticated reg: X0
-// PAUTH-NEXT: safe output registers: LR W30 W30_HI
-// PAUTH-EMPTY:
-// PAUTH-NEXT: Running detailed dst register safety analysis...
-// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state<CannotEscapeUnchecked: , Insts: [0]()>)
-// PAUTH-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
-// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
-// PAUTH-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0](0x{{[0-9a-f]+}} )>)
-// PAUTH-NEXT: After detailed dst register safety analysis:
-// PAUTH-NEXT: Binary Function "auth_oracle" {
-// PAUTH-NEXT: Number : 4
-// PAUTH-NEXT: State : CFG constructed
+// AUTH-ORACLES: BB Layout : [[BB0]]
+// AUTH-ORACLES-NEXT: }
+// AUTH-ORACLES-NEXT: [[BB0]] (2 instructions, align : 1)
+// AUTH-ORACLES-NEXT: Entry Point
+// AUTH-ORACLES-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
+// AUTH-ORACLES-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
+// AUTH-ORACLES-EMPTY:
+// AUTH-ORACLES-NEXT: DWARF CFI Instructions:
+// AUTH-ORACLES-NEXT: <empty>
+// AUTH-ORACLES-NEXT: End of Function "auth_oracle"
+// AUTH-ORACLES-EMPTY:
+// AUTH-ORACLES-NEXT: Found auth inst: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: >
+// AUTH-ORACLES-NEXT: Authenticated reg: X0
+// AUTH-ORACLES-NEXT: safe output registers: LR W30 W30_HI
+// AUTH-ORACLES-EMPTY:
+// AUTH-ORACLES-NEXT: Running detailed dst register safety analysis...
+// AUTH-ORACLES-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state<CannotEscapeUnchecked: , Insts: [0]()>)
+// AUTH-ORACLES-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
+// AUTH-ORACLES-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0]()>)
+// AUTH-ORACLES-NEXT: .. result: (dst-state<CannotEscapeUnchecked: LR W30 W30_HI , Insts: [0](0x{{[0-9a-f]+}} )>)
+// AUTH-ORACLES-NEXT: After detailed dst register safety analysis:
+// AUTH-ORACLES-NEXT: Binary Function "auth_oracle" {
+// AUTH-ORACLES-NEXT: Number : 4
+// AUTH-ORACLES-NEXT: State : CFG constructed
// ...
-// PAUTH: BB Layout : [[BB0]]
-// PAUTH-NEXT: }
-// PAUTH-NEXT: [[BB0]] (2 instructions, align : 1)
-// PAUTH-NEXT: Entry Point
-// PAUTH-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}} )>
-// PAUTH-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0]()>
-// PAUTH-EMPTY:
-// PAUTH-NEXT: DWARF CFI Instructions:
-// PAUTH-NEXT: <empty>
-// PAUTH-NEXT: End of Function "auth_oracle"
-// PAUTH-EMPTY:
-// PAUTH-NEXT: Attaching leakage info to: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}} )>
+// AUTH-ORACLES: BB Layout : [[BB0]]
+// AUTH-ORACLES-NEXT: }
+// AUTH-ORACLES-NEXT: [[BB0]] (2 instructions, align : 1)
+// AUTH-ORACLES-NEXT: Entry Point
+// AUTH-ORACLES-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}} )>
+// AUTH-ORACLES-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0]()>
+// AUTH-ORACLES-EMPTY:
+// AUTH-ORACLES-NEXT: DWARF CFI Instructions:
+// AUTH-ORACLES-NEXT: <empty>
+// AUTH-ORACLES-NEXT: End of Function "auth_oracle"
+// AUTH-ORACLES-EMPTY:
+// AUTH-ORACLES-NEXT: Attaching leakage info to: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector, Insts: [0](0x{{[0-9a-f]+}} )>
// Gadget scanner should not crash on CFI instructions, including when debug-printing them.
// Note that the particular debug output is not checked, but BOLT should be
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s b/bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s
index 5a42ed078e9c2..e1f4fd58bd7b9 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-jump-table.s
@@ -2,9 +2,11 @@
// Without -Wl,--emit-relocs BOLT refuses to create CFG information for the below functions.
// RUN: %clang %cflags -march=armv8.3-a -Wl,--no-relax -Wl,--emit-relocs %s -o %t.exe
-// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck --check-prefixes=CHECK,CFG %s
+// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck --check-prefixes=CHECK,CFG %s
+// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck --check-prefixes=CHECK,CFG %s
// 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 --check-prefixes=CHECK,NOCFG %s
+// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck --check-prefixes=CHECK,NOCFG %s
+// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck --check-prefixes=CHECK,NOCFG %s
// FIXME: Labels could be further validated. Specifically, it could be checked
// that the jump table itself is located in a read-only data section.
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-signing-oracles.s b/bolt/test/binary-analysis/AArch64/gs-pauth-signing-oracles.s
index 94b2c55f3bfa6..0393ac96249e6 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-signing-oracles.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-signing-oracles.s
@@ -1,6 +1,7 @@
// 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 %s
+// 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
// 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
@@ -66,9 +67,10 @@ good_sign_auted_checked_brk:
.globl bad_sign_authed_unchecked
.type bad_sign_authed_unchecked, at function
bad_sign_authed_unchecked:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_sign_authed_unchecked
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
autda x0, x2
pacda x0, x1
ret
@@ -266,9 +268,10 @@ bad_call_between_checked_and_used:
.globl bad_transition_check_then_auth
.type bad_transition_check_then_auth, at function
bad_transition_check_then_auth:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_auth, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_transition_check_then_auth
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_auth, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
ldr x2, [x0]
autda x0, x2
pacda x0, x1
@@ -278,9 +281,10 @@ bad_transition_check_then_auth:
.globl bad_transition_auth_then_auth
.type bad_transition_auth_then_auth, at function
bad_transition_auth_then_auth:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_auth_then_auth, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_transition_auth_then_auth
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_transition_auth_then_auth, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
autda x0, x2
autda x0, x2
pacda x0, x1
@@ -363,9 +367,10 @@ good_sign_auted_checked_brk_multi_bb:
.globl bad_sign_authed_unchecked_multi_bb
.type bad_sign_authed_unchecked_multi_bb, at function
bad_sign_authed_unchecked_multi_bb:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked_multi_bb, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_sign_authed_unchecked_multi_bb
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked_multi_bb, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
autda x0, x2
cbz x3, 1f
ldr x2, [x0]
@@ -534,9 +539,10 @@ good_sign_auted_checked_ldr_nocfg:
.globl bad_sign_authed_unchecked_nocfg
.type bad_sign_authed_unchecked_nocfg, at function
bad_sign_authed_unchecked_nocfg:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_sign_authed_unchecked_nocfg
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
adr x3, 1f
br x3
1:
@@ -640,9 +646,10 @@ bad_clobber_between_checked_and_used_nocfg:
.globl bad_transition_check_then_auth_nocfg
.type bad_transition_check_then_auth_nocfg, at function
bad_transition_check_then_auth_nocfg:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_auth_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_transition_check_then_auth_nocfg
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_auth_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
adr x3, 1f
br x3
1:
@@ -655,9 +662,10 @@ bad_transition_check_then_auth_nocfg:
.globl bad_transition_auth_then_auth_nocfg
.type bad_transition_auth_then_auth_nocfg, at function
bad_transition_auth_then_auth_nocfg:
-// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_auth_then_auth_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// FPAC-NOT: bad_transition_auth_then_auth_nocfg
+// NOFPAC-LABEL: GS-PAUTH: signing oracle found in function bad_transition_auth_then_auth_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
adr x3, 1f
br x3
1:
diff --git a/bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s b/bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s
index 2d3c2f1a632ca..59b7d929275a9 100644
--- a/bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s
+++ b/bolt/test/binary-analysis/AArch64/gs-pauth-tail-calls.s
@@ -1,6 +1,7 @@
// 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 %t.exe 2>&1 | FileCheck %s
+// 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
@@ -89,19 +90,20 @@ bad_indirect_tailcall_not_auted:
.globl bad_direct_tailcall_untrusted
.type bad_direct_tailcall_untrusted, at function
bad_direct_tailcall_untrusted:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
-// CHECK-NEXT: This happens in the following basic block:
-// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
-// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
-// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
-// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: {{[0-9a-f]+}}: b callee # TAILCALL
+// FPAC-NOT: bad_direct_tailcall_untrusted
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
+// NOFPAC-NEXT: This happens in the following basic block:
+// NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
+// NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
+// NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: b callee # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
@@ -114,19 +116,20 @@ bad_direct_tailcall_untrusted:
bad_plt_tailcall_untrusted:
// FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are
// still detected as tail calls.
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
-// CHECK-NEXT: This happens in the following basic block:
-// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
-// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
-// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
-// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
+// FPAC-NOT: bad_plt_tailcall_untrusted
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
+// NOFPAC-NEXT: This happens in the following basic block:
+// NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
+// NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
+// NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
@@ -137,20 +140,21 @@ bad_plt_tailcall_untrusted:
.globl bad_indirect_tailcall_untrusted
.type bad_indirect_tailcall_untrusted, at function
bad_indirect_tailcall_untrusted:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: br x0 # TAILCALL
-// CHECK-NEXT: This happens in the following basic block:
-// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
-// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
-// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
-// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1
-// CHECK-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL
+// FPAC-NOT: bad_indirect_tailcall_untrusted
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: br x0 # TAILCALL
+// NOFPAC-NEXT: This happens in the following basic block:
+// NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
+// NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
+// NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: autia x0, x1
+// NOFPAC-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
@@ -251,13 +255,14 @@ bad_indirect_tailcall_not_auted_multi_bb:
.globl bad_direct_tailcall_untrusted_multi_bb
.type bad_direct_tailcall_untrusted_multi_bb, at function
bad_direct_tailcall_untrusted_multi_bb:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
+// FPAC-NOT: bad_direct_tailcall_untrusted_multi_bb
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
@@ -271,12 +276,13 @@ bad_direct_tailcall_untrusted_multi_bb:
.globl bad_indirect_tailcall_untrusted_multi_bb
.type bad_indirect_tailcall_untrusted_multi_bb, at function
bad_indirect_tailcall_untrusted_multi_bb:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # UNKNOWN CONTROL FLOW
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 0 instructions that leak the affected registers are:
+// FPAC-NOT: bad_indirect_tailcall_untrusted_multi_bb
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # UNKNOWN CONTROL FLOW
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 0 instructions that leak the affected registers are:
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
@@ -397,13 +403,14 @@ bad_indirect_tailcall_not_auted_nocfg:
.globl bad_direct_tailcall_untrusted_nocfg
.type bad_direct_tailcall_untrusted_nocfg, at function
bad_direct_tailcall_untrusted_nocfg:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
+// FPAC-NOT: bad_direct_tailcall_untrusted_nocfg
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
adr x3, 1f
@@ -419,13 +426,14 @@ bad_direct_tailcall_untrusted_nocfg:
bad_plt_tailcall_untrusted_nocfg:
// FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are
// still detected as tail calls.
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL
+// FPAC-NOT: bad_plt_tailcall_untrusted_nocfg
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
adr x3, 1f
@@ -441,11 +449,12 @@ bad_plt_tailcall_untrusted_nocfg:
bad_indirect_tailcall_untrusted_nocfg:
// Known false negative: ignoring UNKNOWN CONTROL FLOW without CFG.
// Authentication oracle is found by a generic checker, though.
-// CHECK-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_nocfg, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 0 instructions that leak the affected registers are:
-// CHECK-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg
+// FPAC-NOT: bad_indirect_tailcall_untrusted_nocfg
+// NOFPAC-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_nocfg, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 0 instructions that leak the affected registers are:
+// NOFPAC-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg
paciasp
stp x29, x30, [sp, #-0x10]!
adr x3, 1f
@@ -515,19 +524,20 @@ good_indirect_tailcall_no_clobber_v83:
.globl bad_indirect_tailcall_untrusted_v83
.type bad_indirect_tailcall_untrusted_v83, at function
bad_indirect_tailcall_untrusted_v83:
-// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
-// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
-// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
-// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: The 1 instructions that leak the affected registers are:
-// CHECK-NEXT: 1. {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
-// CHECK-NEXT: This happens in the following basic block:
-// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
-// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
-// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
-// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
-// CHECK-NEXT: {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
+// FPAC-NOT: bad_indirect_tailcall_untrusted_v83
+// NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
+// NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are:
+// NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
+// NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: The 1 instructions that leak the affected registers are:
+// NOFPAC-NEXT: 1. {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
+// NOFPAC-NEXT: This happens in the following basic block:
+// NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!
+// NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
+// NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp
+// NOFPAC-NEXT: {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
paciasp
stp x29, x30, [sp, #-0x10]!
ldp x29, x30, [sp], #0x10
More information about the llvm-branch-commits
mailing list