Skip to content

[BOLT] Gadget scanner: do not crash on debug-printing CFI instructions #136151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: users/atrosinenko/bolt-gs-auth-oracles
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions bolt/lib/Passes/PAuthGadgetScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ class SrcSafetyAnalysis {
}

SrcState computeNext(const MCInst &Point, const SrcState &Cur) {
if (BC.MIB->isCFI(Point))
return Cur;

SrcStatePrinter P(BC);
LLVM_DEBUG({
dbgs() << " SrcSafetyAnalysis::ComputeNext(";
Expand Down Expand Up @@ -704,6 +707,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
SrcState S = createEntryState();
for (auto &I : BF.instrs()) {
MCInst &Inst = I.second;
if (BC.MIB->isCFI(Inst))
continue;

// If there is a label before this instruction, it is possible that it
// can be jumped-to, thus conservatively resetting S. As an exception,
Expand Down Expand Up @@ -998,6 +1003,9 @@ class DstSafetyAnalysis {
}

DstState computeNext(const MCInst &Point, const DstState &Cur) {
if (BC.MIB->isCFI(Point))
return Cur;

DstStatePrinter P(BC);
LLVM_DEBUG({
dbgs() << " DstSafetyAnalysis::ComputeNext(";
Expand Down Expand Up @@ -1165,6 +1173,8 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis,
DstState S = createUnsafeState();
for (auto &I : llvm::reverse(BF.instrs())) {
MCInst &Inst = I.second;
if (BC.MIB->isCFI(Inst))
continue;

// If Inst can change the control flow, we cannot be sure that the next
// instruction (to be executed in analyzed program) is the one processed
Expand Down Expand Up @@ -1355,6 +1365,9 @@ void FunctionAnalysisContext::findUnsafeUses(
});

iterateOverInstrs(BF, [&](MCInstReference Inst) {
if (BC.MIB->isCFI(Inst))
return;

const SrcState &S = Analysis->getStateBefore(Inst);

// If non-empty state was never propagated from the entry basic block
Expand Down Expand Up @@ -1418,6 +1431,9 @@ void FunctionAnalysisContext::findUnsafeDefs(
});

iterateOverInstrs(BF, [&](MCInstReference Inst) {
if (BC.MIB->isCFI(Inst))
return;

const DstState &S = Analysis->getStateAfter(Inst);

if (auto Report = shouldReportAuthOracle(BC, Inst, S))
Expand Down
32 changes: 32 additions & 0 deletions bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,38 @@ 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]+}} )>

// 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
// compiled with assertions enabled to support -debug-only argument.

.globl cfi_inst_df
.type cfi_inst_df,@function
cfi_inst_df:
.cfi_startproc
sub sp, sp, #16
.cfi_def_cfa_offset 16
add sp, sp, #16
.cfi_def_cfa_offset 0
ret
.size cfi_inst_df, .-cfi_inst_df
.cfi_endproc

.globl cfi_inst_nocfg
.type cfi_inst_nocfg,@function
cfi_inst_nocfg:
.cfi_startproc
sub sp, sp, #16
.cfi_def_cfa_offset 16

adr x0, 1f
br x0
1:
add sp, sp, #16
.cfi_def_cfa_offset 0
ret
.size cfi_inst_nocfg, .-cfi_inst_nocfg
.cfi_endproc

// CHECK-LABEL:Analyzing function main, AllocatorId = 1
.globl main
.type main,@function
Expand Down
Loading