Skip to content

Commit a1dd21d

Browse files
authored
Merge branch 'main' into hgh/libcxx/P2944R3-optional-constrained-equality-part_2
2 parents b1bed3d + 54953b9 commit a1dd21d

File tree

29 files changed

+1467
-649
lines changed

29 files changed

+1467
-649
lines changed

bolt/lib/Passes/PAuthGadgetScanner.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -737,19 +737,14 @@ template <typename StateTy> class CFGUnawareAnalysis {
737737
//
738738
// Then, a function can be split into a number of disjoint contiguous sequences
739739
// of instructions without labels in between. These sequences can be processed
740-
// the same way basic blocks are processed by data-flow analysis, assuming
741-
// pessimistically that all registers are unsafe at the start of each sequence.
740+
// the same way basic blocks are processed by data-flow analysis, with the same
741+
// pessimistic estimation of the initial state at the start of each sequence
742+
// (except the first instruction of the function).
742743
class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
743744
public CFGUnawareAnalysis<SrcState> {
744745
using SrcSafetyAnalysis::BC;
745746
BinaryFunction &BF;
746747

747-
/// Creates a state with all registers marked unsafe (not to be confused
748-
/// with empty state).
749-
SrcState createUnsafeState() const {
750-
return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
751-
}
752-
753748
public:
754749
CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
755750
MCPlusBuilder::AllocatorIdTy AllocId,
@@ -759,6 +754,7 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
759754
}
760755

761756
void run() override {
757+
const SrcState DefaultState = computePessimisticState(BF);
762758
SrcState S = createEntryState();
763759
for (auto &I : BF.instrs()) {
764760
MCInst &Inst = I.second;
@@ -773,7 +769,7 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
773769
LLVM_DEBUG({
774770
traceInst(BC, "Due to label, resetting the state before", Inst);
775771
});
776-
S = createUnsafeState();
772+
S = DefaultState;
777773
}
778774

779775
// Attach the state *before* this instruction executes.

bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -224,20 +224,33 @@ f_unreachable_instruction:
224224
ret
225225
.size f_unreachable_instruction, .-f_unreachable_instruction
226226

227-
// Expected false positive: without CFG, the state is reset to all-unsafe
228-
// after an unconditional branch.
229-
230-
.globl state_is_reset_after_indirect_branch_nocfg
231-
.type state_is_reset_after_indirect_branch_nocfg,@function
232-
state_is_reset_after_indirect_branch_nocfg:
233-
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function state_is_reset_after_indirect_branch_nocfg, at address
234-
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
227+
// Without CFG, the state is reset at labels, assuming every register that can
228+
// be clobbered in the function was actually clobbered.
229+
230+
.globl lr_untouched_nocfg
231+
.type lr_untouched_nocfg,@function
232+
lr_untouched_nocfg:
233+
// CHECK-NOT: lr_untouched_nocfg
234+
adr x2, 1f
235+
br x2
236+
1:
237+
ret
238+
.size lr_untouched_nocfg, .-lr_untouched_nocfg
239+
240+
.globl lr_clobbered_nocfg
241+
.type lr_clobbered_nocfg,@function
242+
lr_clobbered_nocfg:
243+
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function lr_clobbered_nocfg, at address
244+
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
235245
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
236246
adr x2, 1f
237247
br x2
238248
1:
249+
b 2f
250+
bl g // never executed, but affects the expected worst-case scenario
251+
2:
239252
ret
240-
.size state_is_reset_after_indirect_branch_nocfg, .-state_is_reset_after_indirect_branch_nocfg
253+
.size lr_clobbered_nocfg, .-lr_clobbered_nocfg
241254

242255
/// Now do a basic sanity check on every different Authentication instruction:
243256

bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,6 @@ good_address_arith_multi_bb:
491491
ret
492492
.size good_address_arith_multi_bb, .-good_address_arith_multi_bb
493493

494-
// FIXME: Most *_nocfg test cases contain paciasp+autiasp instructions even if
495-
// LR is not spilled - this is a workaround for RET instructions being
496-
// reported as non-protected, because LR state is reset at every label.
497-
498494
.globl good_ret_nocfg
499495
.type good_ret_nocfg,@function
500496
good_ret_nocfg:
@@ -541,29 +537,25 @@ good_branch_nocfg:
541537
.type good_load_other_reg_nocfg,@function
542538
good_load_other_reg_nocfg:
543539
// CHECK-NOT: good_load_other_reg_nocfg
544-
paciasp
545540
adr x2, 1f
546541
br x2
547542
1:
548543
autia x0, x1
549544
ldr x2, [x0]
550545

551-
autiasp
552546
ret
553547
.size good_load_other_reg_nocfg, .-good_load_other_reg_nocfg
554548

555549
.globl good_load_same_reg_nocfg
556550
.type good_load_same_reg_nocfg,@function
557551
good_load_same_reg_nocfg:
558552
// CHECK-NOT: good_load_same_reg_nocfg
559-
paciasp
560553
adr x2, 1f
561554
br x2
562555
1:
563556
autia x0, x1
564557
ldr x0, [x0]
565558

566-
autiasp
567559
ret
568560
.size good_load_same_reg_nocfg, .-good_load_same_reg_nocfg
569561

@@ -575,13 +567,11 @@ bad_unchecked_nocfg:
575567
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_nocfg, at address
576568
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
577569
// CHECK-NEXT: The 0 instructions that leak the affected registers are:
578-
paciasp
579570
adr x2, 1f
580571
br x2
581572
1:
582573
autia x0, x1
583574

584-
autiasp
585575
ret
586576
.size bad_unchecked_nocfg, .-bad_unchecked_nocfg
587577

@@ -615,15 +605,13 @@ bad_unknown_usage_read_nocfg:
615605
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
616606
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
617607
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1
618-
paciasp
619608
adr x2, 1f
620609
br x2
621610
1:
622611
autia x0, x1
623612
mul x3, x0, x1
624613
ldr x2, [x0]
625614

626-
autiasp
627615
ret
628616
.size bad_unknown_usage_read_nocfg, .-bad_unknown_usage_read_nocfg
629617

@@ -634,15 +622,13 @@ bad_unknown_usage_subreg_read_nocfg:
634622
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
635623
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
636624
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1
637-
paciasp
638625
adr x2, 1f
639626
br x2
640627
1:
641628
autia x0, x1
642629
mul w3, w0, w1
643630
ldr x2, [x0]
644631

645-
autiasp
646632
ret
647633
.size bad_unknown_usage_subreg_read_nocfg, .-bad_unknown_usage_subreg_read_nocfg
648634

@@ -653,38 +639,33 @@ bad_unknown_usage_update_nocfg:
653639
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
654640
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
655641
// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16
656-
paciasp
657642
adr x2, 1f
658643
br x2
659644
1:
660645
autia x0, x1
661646
movk x0, #42, lsl #16 // does not overwrite x0 completely
662647
ldr x2, [x0]
663648

664-
autiasp
665649
ret
666650
.size bad_unknown_usage_update_nocfg, .-bad_unknown_usage_update_nocfg
667651

668652
.globl good_overwrite_with_constant_nocfg
669653
.type good_overwrite_with_constant_nocfg,@function
670654
good_overwrite_with_constant_nocfg:
671655
// CHECK-NOT: good_overwrite_with_constant_nocfg
672-
paciasp
673656
adr x2, 1f
674657
br x2
675658
1:
676659
autia x0, x1
677660
mov x0, #42
678661

679-
autiasp
680662
ret
681663
.size good_overwrite_with_constant_nocfg, .-good_overwrite_with_constant_nocfg
682664

683665
.globl good_address_arith_nocfg
684666
.type good_address_arith_nocfg,@function
685667
good_address_arith_nocfg:
686668
// CHECK-NOT: good_address_arith_nocfg
687-
paciasp
688669
adr x2, 1f
689670
br x2
690671
1:
@@ -698,7 +679,6 @@ good_address_arith_nocfg:
698679
mov x1, #0
699680
mov x2, #0
700681

701-
autiasp
702682
ret
703683
.size good_address_arith_nocfg, .-good_address_arith_nocfg
704684

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

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ nocfg:
199199
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( br x0, src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
200200
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
201201
// CHECK-NEXT: Due to label, resetting the state before: 00000000: ret # Offset: 8
202-
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
203-
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
202+
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
203+
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
204204
// CHECK-NEXT: After src register safety analysis:
205205
// CHECK-NEXT: Binary Function "nocfg" {
206206
// CHECK-NEXT: Number : 3
@@ -223,33 +223,7 @@ nocfg:
223223
// PAUTH-NEXT: SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI{{[ \t]*$}}
224224
// CHECK-NEXT: Found RET inst: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
225225
// CHECK-NEXT: RetReg: LR
226-
// CHECK-NEXT: SafeToDerefRegs:{{[ \t]*$}}
227-
// CHECK-EMPTY:
228-
// CHECK-NEXT: Running detailed src register safety analysis...
229-
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( adr x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]], src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: [0]()>)
230-
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: [0]()>)
231-
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( br x0, src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: [0]()>)
232-
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: [0]()>)
233-
// CHECK-NEXT: Due to label, resetting the state before: 00000000: ret # Offset: 8
234-
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: [0]()>)
235-
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: [0]()>)
236-
// CHECK-NEXT: After detailed src register safety analysis:
237-
// CHECK-NEXT: Binary Function "nocfg" {
238-
// CHECK-NEXT: Number : 3
239-
// ...
240-
// CHECK: Secondary Entry Points : __ENTRY_nocfg@0x[[ENTRY_ADDR]]
241-
// CHECK-NEXT: }
242-
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
243-
// CHECK-NEXT: 00000000: adr x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]] # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
244-
// CHECK-NEXT: 00000004: br x0 # UNKNOWN CONTROL FLOW # Offset: 4 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
245-
// CHECK-NEXT: __ENTRY_nocfg@0x[[ENTRY_ADDR]] (Entry Point):
246-
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
247-
// CHECK-NEXT: 00000008: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
248-
// CHECK-NEXT: DWARF CFI Instructions:
249-
// CHECK-NEXT: <empty>
250-
// CHECK-NEXT: End of Function "nocfg"
251-
// CHECK-EMPTY:
252-
// CHECK-NEXT: Attaching clobbering info to: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
226+
// CHECK-NEXT: SafeToDerefRegs: LR W30 W30_HI{{[ \t]*$}}
253227

254228
.globl auth_oracle
255229
.type auth_oracle,@function

0 commit comments

Comments
 (0)