[BOLT] Gadget scanner: fix LR to be safe in leaf functions without CFG (#141824)
After a label in a function without CFG information, use a reasonably pessimistic estimation of register state (assume that any register that can be clobbered in this function was actually clobbered) instead of the most pessimistic "all registers are unsafe". This is the same estimation as used by the dataflow variant of the analysis when the preceding instruction is not known for sure. Without this, leaf functions without CFG information are likely to have false positive reports about non-protected return instructions, as 1) LR is unlikely to be signed and authenticated in a leaf function and 2) LR is likely to be used by a return instruction near the end of the function and 3) the register state is likely to be reset at least once during the linear scan through the function
This commit is contained in:
parent
36a060a4e5
commit
a8a2c6fa88
@ -737,19 +737,14 @@ protected:
|
|||||||
//
|
//
|
||||||
// Then, a function can be split into a number of disjoint contiguous sequences
|
// Then, a function can be split into a number of disjoint contiguous sequences
|
||||||
// of instructions without labels in between. These sequences can be processed
|
// of instructions without labels in between. These sequences can be processed
|
||||||
// the same way basic blocks are processed by data-flow analysis, assuming
|
// the same way basic blocks are processed by data-flow analysis, with the same
|
||||||
// pessimistically that all registers are unsafe at the start of each sequence.
|
// pessimistic estimation of the initial state at the start of each sequence
|
||||||
|
// (except the first instruction of the function).
|
||||||
class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
|
class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis,
|
||||||
public CFGUnawareAnalysis<SrcState> {
|
public CFGUnawareAnalysis<SrcState> {
|
||||||
using SrcSafetyAnalysis::BC;
|
using SrcSafetyAnalysis::BC;
|
||||||
BinaryFunction &BF;
|
BinaryFunction &BF;
|
||||||
|
|
||||||
/// Creates a state with all registers marked unsafe (not to be confused
|
|
||||||
/// with empty state).
|
|
||||||
SrcState createUnsafeState() const {
|
|
||||||
return SrcState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
|
CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF,
|
||||||
MCPlusBuilder::AllocatorIdTy AllocId,
|
MCPlusBuilder::AllocatorIdTy AllocId,
|
||||||
@ -759,6 +754,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
|
const SrcState DefaultState = computePessimisticState(BF);
|
||||||
SrcState S = createEntryState();
|
SrcState S = createEntryState();
|
||||||
for (auto &I : BF.instrs()) {
|
for (auto &I : BF.instrs()) {
|
||||||
MCInst &Inst = I.second;
|
MCInst &Inst = I.second;
|
||||||
@ -773,7 +769,7 @@ public:
|
|||||||
LLVM_DEBUG({
|
LLVM_DEBUG({
|
||||||
traceInst(BC, "Due to label, resetting the state before", Inst);
|
traceInst(BC, "Due to label, resetting the state before", Inst);
|
||||||
});
|
});
|
||||||
S = createUnsafeState();
|
S = DefaultState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the state *before* this instruction executes.
|
// Attach the state *before* this instruction executes.
|
||||||
|
@ -224,20 +224,33 @@ f_unreachable_instruction:
|
|||||||
ret
|
ret
|
||||||
.size f_unreachable_instruction, .-f_unreachable_instruction
|
.size f_unreachable_instruction, .-f_unreachable_instruction
|
||||||
|
|
||||||
// Expected false positive: without CFG, the state is reset to all-unsafe
|
// Without CFG, the state is reset at labels, assuming every register that can
|
||||||
// after an unconditional branch.
|
// be clobbered in the function was actually clobbered.
|
||||||
|
|
||||||
.globl state_is_reset_after_indirect_branch_nocfg
|
.globl lr_untouched_nocfg
|
||||||
.type state_is_reset_after_indirect_branch_nocfg,@function
|
.type lr_untouched_nocfg,@function
|
||||||
state_is_reset_after_indirect_branch_nocfg:
|
lr_untouched_nocfg:
|
||||||
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function state_is_reset_after_indirect_branch_nocfg, at address
|
// CHECK-NOT: lr_untouched_nocfg
|
||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
||||||
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
ret
|
ret
|
||||||
.size state_is_reset_after_indirect_branch_nocfg, .-state_is_reset_after_indirect_branch_nocfg
|
.size lr_untouched_nocfg, .-lr_untouched_nocfg
|
||||||
|
|
||||||
|
.globl lr_clobbered_nocfg
|
||||||
|
.type lr_clobbered_nocfg,@function
|
||||||
|
lr_clobbered_nocfg:
|
||||||
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function lr_clobbered_nocfg, at address
|
||||||
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
||||||
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
|
adr x2, 1f
|
||||||
|
br x2
|
||||||
|
1:
|
||||||
|
b 2f
|
||||||
|
bl g // never executed, but affects the expected worst-case scenario
|
||||||
|
2:
|
||||||
|
ret
|
||||||
|
.size lr_clobbered_nocfg, .-lr_clobbered_nocfg
|
||||||
|
|
||||||
/// Now do a basic sanity check on every different Authentication instruction:
|
/// Now do a basic sanity check on every different Authentication instruction:
|
||||||
|
|
||||||
|
@ -491,10 +491,6 @@ good_address_arith_multi_bb:
|
|||||||
ret
|
ret
|
||||||
.size good_address_arith_multi_bb, .-good_address_arith_multi_bb
|
.size good_address_arith_multi_bb, .-good_address_arith_multi_bb
|
||||||
|
|
||||||
// FIXME: Most *_nocfg test cases contain paciasp+autiasp instructions even if
|
|
||||||
// LR is not spilled - this is a workaround for RET instructions being
|
|
||||||
// reported as non-protected, because LR state is reset at every label.
|
|
||||||
|
|
||||||
.globl good_ret_nocfg
|
.globl good_ret_nocfg
|
||||||
.type good_ret_nocfg,@function
|
.type good_ret_nocfg,@function
|
||||||
good_ret_nocfg:
|
good_ret_nocfg:
|
||||||
@ -541,14 +537,12 @@ good_branch_nocfg:
|
|||||||
.type good_load_other_reg_nocfg,@function
|
.type good_load_other_reg_nocfg,@function
|
||||||
good_load_other_reg_nocfg:
|
good_load_other_reg_nocfg:
|
||||||
// CHECK-NOT: good_load_other_reg_nocfg
|
// CHECK-NOT: good_load_other_reg_nocfg
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
autia x0, x1
|
autia x0, x1
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_load_other_reg_nocfg, .-good_load_other_reg_nocfg
|
.size good_load_other_reg_nocfg, .-good_load_other_reg_nocfg
|
||||||
|
|
||||||
@ -556,14 +550,12 @@ good_load_other_reg_nocfg:
|
|||||||
.type good_load_same_reg_nocfg,@function
|
.type good_load_same_reg_nocfg,@function
|
||||||
good_load_same_reg_nocfg:
|
good_load_same_reg_nocfg:
|
||||||
// CHECK-NOT: good_load_same_reg_nocfg
|
// CHECK-NOT: good_load_same_reg_nocfg
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
autia x0, x1
|
autia x0, x1
|
||||||
ldr x0, [x0]
|
ldr x0, [x0]
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_load_same_reg_nocfg, .-good_load_same_reg_nocfg
|
.size good_load_same_reg_nocfg, .-good_load_same_reg_nocfg
|
||||||
|
|
||||||
@ -575,13 +567,11 @@ bad_unchecked_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_nocfg, at address
|
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_nocfg, at address
|
||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
||||||
// CHECK-NEXT: The 0 instructions that leak the affected registers are:
|
// CHECK-NEXT: The 0 instructions that leak the affected registers are:
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
autia x0, x1
|
autia x0, x1
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_unchecked_nocfg, .-bad_unchecked_nocfg
|
.size bad_unchecked_nocfg, .-bad_unchecked_nocfg
|
||||||
|
|
||||||
@ -615,7 +605,6 @@ bad_unknown_usage_read_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
@ -623,7 +612,6 @@ bad_unknown_usage_read_nocfg:
|
|||||||
mul x3, x0, x1
|
mul x3, x0, x1
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_unknown_usage_read_nocfg, .-bad_unknown_usage_read_nocfg
|
.size bad_unknown_usage_read_nocfg, .-bad_unknown_usage_read_nocfg
|
||||||
|
|
||||||
@ -634,7 +622,6 @@ bad_unknown_usage_subreg_read_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
@ -642,7 +629,6 @@ bad_unknown_usage_subreg_read_nocfg:
|
|||||||
mul w3, w0, w1
|
mul w3, w0, w1
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_unknown_usage_subreg_read_nocfg, .-bad_unknown_usage_subreg_read_nocfg
|
.size bad_unknown_usage_subreg_read_nocfg, .-bad_unknown_usage_subreg_read_nocfg
|
||||||
|
|
||||||
@ -653,7 +639,6 @@ bad_unknown_usage_update_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
@ -661,7 +646,6 @@ bad_unknown_usage_update_nocfg:
|
|||||||
movk x0, #42, lsl #16 // does not overwrite x0 completely
|
movk x0, #42, lsl #16 // does not overwrite x0 completely
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_unknown_usage_update_nocfg, .-bad_unknown_usage_update_nocfg
|
.size bad_unknown_usage_update_nocfg, .-bad_unknown_usage_update_nocfg
|
||||||
|
|
||||||
@ -669,14 +653,12 @@ bad_unknown_usage_update_nocfg:
|
|||||||
.type good_overwrite_with_constant_nocfg,@function
|
.type good_overwrite_with_constant_nocfg,@function
|
||||||
good_overwrite_with_constant_nocfg:
|
good_overwrite_with_constant_nocfg:
|
||||||
// CHECK-NOT: good_overwrite_with_constant_nocfg
|
// CHECK-NOT: good_overwrite_with_constant_nocfg
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
autia x0, x1
|
autia x0, x1
|
||||||
mov x0, #42
|
mov x0, #42
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_overwrite_with_constant_nocfg, .-good_overwrite_with_constant_nocfg
|
.size good_overwrite_with_constant_nocfg, .-good_overwrite_with_constant_nocfg
|
||||||
|
|
||||||
@ -684,7 +666,6 @@ good_overwrite_with_constant_nocfg:
|
|||||||
.type good_address_arith_nocfg,@function
|
.type good_address_arith_nocfg,@function
|
||||||
good_address_arith_nocfg:
|
good_address_arith_nocfg:
|
||||||
// CHECK-NOT: good_address_arith_nocfg
|
// CHECK-NOT: good_address_arith_nocfg
|
||||||
paciasp
|
|
||||||
adr x2, 1f
|
adr x2, 1f
|
||||||
br x2
|
br x2
|
||||||
1:
|
1:
|
||||||
@ -698,7 +679,6 @@ good_address_arith_nocfg:
|
|||||||
mov x1, #0
|
mov x1, #0
|
||||||
mov x2, #0
|
mov x2, #0
|
||||||
|
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_address_arith_nocfg, .-good_address_arith_nocfg
|
.size good_address_arith_nocfg, .-good_address_arith_nocfg
|
||||||
|
|
||||||
|
@ -199,8 +199,8 @@ nocfg:
|
|||||||
// 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: >)
|
// 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: >)
|
||||||
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
|
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI , TrustedRegs: LR W0 W30 X0 W0_HI W30_HI , Insts: >)
|
||||||
// CHECK-NEXT: Due to label, resetting the state before: 00000000: ret # Offset: 8
|
// CHECK-NEXT: Due to label, resetting the state before: 00000000: ret # Offset: 8
|
||||||
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
|
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
|
||||||
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: >)
|
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: LR W30 W30_HI , TrustedRegs: LR W30 W30_HI , Insts: >)
|
||||||
// CHECK-NEXT: After src register safety analysis:
|
// CHECK-NEXT: After src register safety analysis:
|
||||||
// CHECK-NEXT: Binary Function "nocfg" {
|
// CHECK-NEXT: Binary Function "nocfg" {
|
||||||
// CHECK-NEXT: Number : 3
|
// CHECK-NEXT: Number : 3
|
||||||
@ -223,33 +223,7 @@ nocfg:
|
|||||||
// PAUTH-NEXT: SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI{{[ \t]*$}}
|
// PAUTH-NEXT: SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI{{[ \t]*$}}
|
||||||
// CHECK-NEXT: Found RET inst: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
|
// CHECK-NEXT: Found RET inst: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: >
|
||||||
// CHECK-NEXT: RetReg: LR
|
// CHECK-NEXT: RetReg: LR
|
||||||
// CHECK-NEXT: SafeToDerefRegs:{{[ \t]*$}}
|
// CHECK-NEXT: SafeToDerefRegs: LR W30 W30_HI{{[ \t]*$}}
|
||||||
// CHECK-EMPTY:
|
|
||||||
// CHECK-NEXT: Running detailed src register safety analysis...
|
|
||||||
// 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]()>)
|
|
||||||
// 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]()>)
|
|
||||||
// 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]()>)
|
|
||||||
// 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]()>)
|
|
||||||
// CHECK-NEXT: Due to label, resetting the state before: 00000000: ret # Offset: 8
|
|
||||||
// CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( ret x30, src-state<SafeToDerefRegs: , TrustedRegs: , Insts: [0]()>)
|
|
||||||
// CHECK-NEXT: .. result: (src-state<SafeToDerefRegs: , TrustedRegs: , Insts: [0]()>)
|
|
||||||
// CHECK-NEXT: After detailed src register safety analysis:
|
|
||||||
// CHECK-NEXT: Binary Function "nocfg" {
|
|
||||||
// CHECK-NEXT: Number : 3
|
|
||||||
// ...
|
|
||||||
// CHECK: Secondary Entry Points : __ENTRY_nocfg@0x[[ENTRY_ADDR]]
|
|
||||||
// CHECK-NEXT: }
|
|
||||||
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
|
|
||||||
// CHECK-NEXT: 00000000: adr x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]] # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
|
|
||||||
// CHECK-NEXT: 00000004: br x0 # UNKNOWN CONTROL FLOW # Offset: 4 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
|
|
||||||
// CHECK-NEXT: __ENTRY_nocfg@0x[[ENTRY_ADDR]] (Entry Point):
|
|
||||||
// CHECK-NEXT: .{{[A-Za-z0-9]+}}:
|
|
||||||
// CHECK-NEXT: 00000008: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
|
|
||||||
// CHECK-NEXT: DWARF CFI Instructions:
|
|
||||||
// CHECK-NEXT: <empty>
|
|
||||||
// CHECK-NEXT: End of Function "nocfg"
|
|
||||||
// CHECK-EMPTY:
|
|
||||||
// CHECK-NEXT: Attaching clobbering info to: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state<SafeToDerefRegs: BitVector, TrustedRegs: BitVector, Insts: [0]()>
|
|
||||||
|
|
||||||
.globl auth_oracle
|
.globl auth_oracle
|
||||||
.type auth_oracle,@function
|
.type auth_oracle,@function
|
||||||
|
@ -505,21 +505,16 @@ bad_one_auted_one_checked_multi_bb:
|
|||||||
// * untrusted: not even s-t-d - from arg and from memory
|
// * untrusted: not even s-t-d - from arg and from memory
|
||||||
// * untrusted: subreg clobbered - between address materialization and use, between auth and check, between check and use
|
// * untrusted: subreg clobbered - between address materialization and use, between auth and check, between check and use
|
||||||
// * untrusted: first checked then auted, auted then auted, checked then checked
|
// * untrusted: first checked then auted, auted then auted, checked then checked
|
||||||
//
|
|
||||||
// Note that it is important to sign and authenticate LR, as it is not kept
|
|
||||||
// safe-to-dereference across unconditional branches.
|
|
||||||
|
|
||||||
.globl good_sign_addr_mat_nocfg
|
.globl good_sign_addr_mat_nocfg
|
||||||
.type good_sign_addr_mat_nocfg,@function
|
.type good_sign_addr_mat_nocfg,@function
|
||||||
good_sign_addr_mat_nocfg:
|
good_sign_addr_mat_nocfg:
|
||||||
// CHECK-NOT: good_sign_addr_mat_nocfg
|
// CHECK-NOT: good_sign_addr_mat_nocfg
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
adr x0, sym
|
adr x0, sym
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_sign_addr_mat_nocfg, .-good_sign_addr_mat_nocfg
|
.size good_sign_addr_mat_nocfg, .-good_sign_addr_mat_nocfg
|
||||||
|
|
||||||
@ -527,14 +522,12 @@ good_sign_addr_mat_nocfg:
|
|||||||
.type good_sign_auted_checked_ldr_nocfg,@function
|
.type good_sign_auted_checked_ldr_nocfg,@function
|
||||||
good_sign_auted_checked_ldr_nocfg:
|
good_sign_auted_checked_ldr_nocfg:
|
||||||
// CHECK-NOT: good_sign_auted_checked_ldr_nocfg
|
// CHECK-NOT: good_sign_auted_checked_ldr_nocfg
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
autda x0, x2
|
autda x0, x2
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size good_sign_auted_checked_ldr_nocfg, .-good_sign_auted_checked_ldr_nocfg
|
.size good_sign_auted_checked_ldr_nocfg, .-good_sign_auted_checked_ldr_nocfg
|
||||||
|
|
||||||
@ -544,13 +537,11 @@ bad_sign_authed_unchecked_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_authed_unchecked_nocfg, at address
|
// 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 instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
autda x0, x2
|
autda x0, x2
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_sign_authed_unchecked_nocfg, .-bad_sign_authed_unchecked_nocfg
|
.size bad_sign_authed_unchecked_nocfg, .-bad_sign_authed_unchecked_nocfg
|
||||||
|
|
||||||
@ -560,13 +551,11 @@ bad_sign_checked_not_auted_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_checked_not_auted_nocfg, at address
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_checked_not_auted_nocfg, at address
|
||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// 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:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_sign_checked_not_auted_nocfg, .-bad_sign_checked_not_auted_nocfg
|
.size bad_sign_checked_not_auted_nocfg, .-bad_sign_checked_not_auted_nocfg
|
||||||
|
|
||||||
@ -576,12 +565,10 @@ bad_sign_plain_arg_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_plain_arg_nocfg, at address
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_sign_plain_arg_nocfg, at address
|
||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// 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:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_sign_plain_arg_nocfg, .-bad_sign_plain_arg_nocfg
|
.size bad_sign_plain_arg_nocfg, .-bad_sign_plain_arg_nocfg
|
||||||
|
|
||||||
@ -592,13 +579,11 @@ bad_sign_plain_mem_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: ldr x0, [x1]
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: ldr x0, [x1]
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
ldr x0, [x1]
|
ldr x0, [x1]
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_sign_plain_mem_nocfg, .-bad_sign_plain_mem_nocfg
|
.size bad_sign_plain_mem_nocfg, .-bad_sign_plain_mem_nocfg
|
||||||
|
|
||||||
@ -609,14 +594,12 @@ bad_clobber_between_addr_mat_and_use_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
adr x0, sym
|
adr x0, sym
|
||||||
mov w0, w4
|
mov w0, w4
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_clobber_between_addr_mat_and_use_nocfg, .-bad_clobber_between_addr_mat_and_use_nocfg
|
.size bad_clobber_between_addr_mat_and_use_nocfg, .-bad_clobber_between_addr_mat_and_use_nocfg
|
||||||
|
|
||||||
@ -627,7 +610,6 @@ bad_clobber_between_auted_and_checked_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
@ -635,7 +617,6 @@ bad_clobber_between_auted_and_checked_nocfg:
|
|||||||
mov w0, w4
|
mov w0, w4
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_clobber_between_auted_and_checked_nocfg, .-bad_clobber_between_auted_and_checked_nocfg
|
.size bad_clobber_between_auted_and_checked_nocfg, .-bad_clobber_between_auted_and_checked_nocfg
|
||||||
|
|
||||||
@ -646,7 +627,6 @@ bad_clobber_between_checked_and_used_nocfg:
|
|||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
||||||
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w0, w4
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
@ -654,7 +634,6 @@ bad_clobber_between_checked_and_used_nocfg:
|
|||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
mov w0, w4
|
mov w0, w4
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_clobber_between_checked_and_used_nocfg, .-bad_clobber_between_checked_and_used_nocfg
|
.size bad_clobber_between_checked_and_used_nocfg, .-bad_clobber_between_checked_and_used_nocfg
|
||||||
|
|
||||||
@ -664,14 +643,12 @@ bad_transition_check_then_auth_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_auth_nocfg, at address
|
// 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 instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
autda x0, x2
|
autda x0, x2
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_transition_check_then_auth_nocfg, .-bad_transition_check_then_auth_nocfg
|
.size bad_transition_check_then_auth_nocfg, .-bad_transition_check_then_auth_nocfg
|
||||||
|
|
||||||
@ -681,14 +658,12 @@ bad_transition_auth_then_auth_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_auth_then_auth_nocfg, at address
|
// 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 instruction is {{[0-9a-f]+}}: pacda x0, x1
|
||||||
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
autda x0, x2
|
autda x0, x2
|
||||||
autda x0, x2
|
autda x0, x2
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_transition_auth_then_auth_nocfg, .-bad_transition_auth_then_auth_nocfg
|
.size bad_transition_auth_then_auth_nocfg, .-bad_transition_auth_then_auth_nocfg
|
||||||
|
|
||||||
@ -698,14 +673,12 @@ bad_transition_check_then_check_nocfg:
|
|||||||
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_check_nocfg, at address
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_transition_check_then_check_nocfg, at address
|
||||||
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: pacda x0, x1
|
// 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:
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
||||||
paciasp
|
|
||||||
adr x3, 1f
|
adr x3, 1f
|
||||||
br x3
|
br x3
|
||||||
1:
|
1:
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
ldr x2, [x0]
|
ldr x2, [x0]
|
||||||
pacda x0, x1
|
pacda x0, x1
|
||||||
autiasp
|
|
||||||
ret
|
ret
|
||||||
.size bad_transition_check_then_check_nocfg, .-bad_transition_check_then_check_nocfg
|
.size bad_transition_check_then_check_nocfg, .-bad_transition_check_then_check_nocfg
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user