Skip to content

Commit e22ae5e

Browse files
committed
[BOLT] Gadget scanner: do not crash on debug-printing CFI instructions
Some instruction-printing code used under LLVM_DEBUG does not handle CFI instructions well. While CFI instructions seem to be harmless for the correctness of the analysis results, they do not convey any useful information to the analysis either, so skip them early.
1 parent c65779c commit e22ae5e

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

bolt/lib/Passes/PAuthGadgetScanner.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ class SrcSafetyAnalysis {
431431
}
432432

433433
SrcState computeNext(const MCInst &Point, const SrcState &Cur) {
434+
if (BC.MIB->isCFI(Point))
435+
return Cur;
436+
434437
SrcStatePrinter P(BC);
435438
LLVM_DEBUG({
436439
dbgs() << " SrcSafetyAnalysis::ComputeNext(";
@@ -670,6 +673,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis {
670673
SrcState S = createEntryState();
671674
for (auto &I : BF.instrs()) {
672675
MCInst &Inst = I.second;
676+
if (BC.MIB->isCFI(Inst))
677+
continue;
673678

674679
// If there is a label before this instruction, it is possible that it
675680
// can be jumped-to, thus conservatively resetting S. As an exception,
@@ -947,6 +952,9 @@ class DstSafetyAnalysis {
947952
}
948953

949954
DstState computeNext(const MCInst &Point, const DstState &Cur) {
955+
if (BC.MIB->isCFI(Point))
956+
return Cur;
957+
950958
DstStatePrinter P(BC);
951959
LLVM_DEBUG({
952960
dbgs() << " DstSafetyAnalysis::ComputeNext(";
@@ -1123,6 +1131,8 @@ class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis {
11231131
DstState S = createUnsafeState();
11241132
for (auto &I : llvm::reverse(BF.instrs())) {
11251133
MCInst &Inst = I.second;
1134+
if (BC.MIB->isCFI(Inst))
1135+
continue;
11261136

11271137
// If Inst can change the control flow, we cannot be sure that the next
11281138
// instruction (to be executed in analyzed program) is the one processed
@@ -1319,6 +1329,9 @@ void FunctionAnalysis::findUnsafeUses(
13191329
});
13201330

13211331
iterateOverInstrs(BF, [&](MCInstReference Inst) {
1332+
if (BC.MIB->isCFI(Inst))
1333+
return;
1334+
13221335
const SrcState &S = Analysis->getStateBefore(Inst);
13231336

13241337
// If non-empty state was never propagated from the entry basic block
@@ -1382,6 +1395,9 @@ void FunctionAnalysis::findUnsafeDefs(
13821395
});
13831396

13841397
iterateOverInstrs(BF, [&](MCInstReference Inst) {
1398+
if (BC.MIB->isCFI(Inst))
1399+
return;
1400+
13851401
const DstState &S = Analysis->getStateAfter(Inst);
13861402

13871403
if (auto Report = shouldReportAuthOracle(BC, Inst, S))

bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s

+32
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,38 @@ auth_oracle:
329329
// PAUTH-EMPTY:
330330
// PAUTH-NEXT: Attaching leakage info to: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state<CannotEscapeUnchecked: BitVector>
331331

332+
// Gadget scanner should not crash on CFI instructions, including when debug-printing them.
333+
// Note that the particular debug output is not checked, but BOLT should be
334+
// compiled with assertions enabled to support -debug-only argument.
335+
336+
.globl cfi_inst_df
337+
.type cfi_inst_df,@function
338+
cfi_inst_df:
339+
.cfi_startproc
340+
sub sp, sp, #16
341+
.cfi_def_cfa_offset 16
342+
add sp, sp, #16
343+
.cfi_def_cfa_offset 0
344+
ret
345+
.size cfi_inst_df, .-cfi_inst_df
346+
.cfi_endproc
347+
348+
.globl cfi_inst_nocfg
349+
.type cfi_inst_nocfg,@function
350+
cfi_inst_nocfg:
351+
.cfi_startproc
352+
sub sp, sp, #16
353+
.cfi_def_cfa_offset 16
354+
355+
adr x0, 1f
356+
br x0
357+
1:
358+
add sp, sp, #16
359+
.cfi_def_cfa_offset 0
360+
ret
361+
.size cfi_inst_nocfg, .-cfi_inst_nocfg
362+
.cfi_endproc
363+
332364
// CHECK-LABEL:Analyzing function main, AllocatorId = 1
333365
.globl main
334366
.type main,@function

0 commit comments

Comments
 (0)