[arm64] Use B instruction key for return address signing
The C++ code uses the A instruction key for return address signing, which is the default for Clang and GCC when the -mbranch-protection option is used (although this can be configured to use the B key). Using the B key for JS means that it's not possible to use an A key signing gadget to replace a return address signed with the B key and vice-versa. This should offer a degree of separation from the C++ side. Bug: v8:10026 Change-Id: Ia9dcc7ae7096c96b4a271efbe25fc02940f6fc8e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2242953 Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Georgia Kouveli <georgia.kouveli@arm.com> Cr-Commit-Position: refs/heads/master@{#68360}
This commit is contained in:
parent
637f04f66a
commit
c65c1c10a5
@ -1162,10 +1162,10 @@ void Assembler::cls(const Register& rd, const Register& rn) {
|
||||
DataProcessing1Source(rd, rn, CLS);
|
||||
}
|
||||
|
||||
void Assembler::pacia1716() { Emit(PACIA1716); }
|
||||
void Assembler::autia1716() { Emit(AUTIA1716); }
|
||||
void Assembler::paciasp() { Emit(PACIASP); }
|
||||
void Assembler::autiasp() { Emit(AUTIASP); }
|
||||
void Assembler::pacib1716() { Emit(PACIB1716); }
|
||||
void Assembler::autib1716() { Emit(AUTIB1716); }
|
||||
void Assembler::pacibsp() { Emit(PACIBSP); }
|
||||
void Assembler::autibsp() { Emit(AUTIBSP); }
|
||||
|
||||
void Assembler::bti(BranchTargetIdentifier id) {
|
||||
SystemHint op;
|
||||
@ -1183,9 +1183,9 @@ void Assembler::bti(BranchTargetIdentifier id) {
|
||||
op = BTI_jc;
|
||||
break;
|
||||
case BranchTargetIdentifier::kNone:
|
||||
case BranchTargetIdentifier::kPaciasp:
|
||||
case BranchTargetIdentifier::kPacibsp:
|
||||
// We always want to generate a BTI instruction here, so disallow
|
||||
// skipping its generation or generating a PACIASP instead.
|
||||
// skipping its generation or generating a PACIBSP instead.
|
||||
UNREACHABLE();
|
||||
}
|
||||
hint(op);
|
||||
|
@ -780,21 +780,21 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
||||
void clz(const Register& rd, const Register& rn);
|
||||
void cls(const Register& rd, const Register& rn);
|
||||
|
||||
// Pointer Authentication Code for Instruction address, using key A, with
|
||||
// Pointer Authentication Code for Instruction address, using key B, with
|
||||
// address in x17 and modifier in x16 [Armv8.3].
|
||||
void pacia1716();
|
||||
void pacib1716();
|
||||
|
||||
// Pointer Authentication Code for Instruction address, using key A, with
|
||||
// Pointer Authentication Code for Instruction address, using key B, with
|
||||
// address in LR and modifier in SP [Armv8.3].
|
||||
void paciasp();
|
||||
void pacibsp();
|
||||
|
||||
// Authenticate Instruction address, using key A, with address in x17 and
|
||||
// Authenticate Instruction address, using key B, with address in x17 and
|
||||
// modifier in x16 [Armv8.3].
|
||||
void autia1716();
|
||||
void autib1716();
|
||||
|
||||
// Authenticate Instruction address, using key A, with address in LR and
|
||||
// Authenticate Instruction address, using key B, with address in LR and
|
||||
// modifier in SP [Armv8.3].
|
||||
void autiasp();
|
||||
void autibsp();
|
||||
|
||||
// Memory instructions.
|
||||
|
||||
|
@ -412,9 +412,9 @@ enum class BranchTargetIdentifier {
|
||||
// Emit a "BTI jc" instruction, which is a combination of "BTI j" and "BTI c".
|
||||
kBtiJumpCall,
|
||||
|
||||
// Emit a PACIASP instruction, which acts like a "BTI c" or a "BTI jc", based
|
||||
// on the value of SCTLR_EL1.BT0.
|
||||
kPaciasp
|
||||
// Emit a PACIBSP instruction, which acts like a "BTI c" or a "BTI jc",
|
||||
// based on the value of SCTLR_EL1.BT0.
|
||||
kPacibsp
|
||||
};
|
||||
|
||||
enum BarrierDomain {
|
||||
@ -793,10 +793,10 @@ enum SystemPAuthOp : uint32_t {
|
||||
SystemPAuthFixed = 0xD503211F,
|
||||
SystemPAuthFMask = 0xFFFFFD1F,
|
||||
SystemPAuthMask = 0xFFFFFFFF,
|
||||
PACIA1716 = SystemPAuthFixed | 0x00000100,
|
||||
AUTIA1716 = SystemPAuthFixed | 0x00000180,
|
||||
PACIASP = SystemPAuthFixed | 0x00000320,
|
||||
AUTIASP = SystemPAuthFixed | 0x000003A0
|
||||
PACIB1716 = SystemPAuthFixed | 0x00000140,
|
||||
AUTIB1716 = SystemPAuthFixed | 0x000001C0,
|
||||
PACIBSP = SystemPAuthFixed | 0x00000360,
|
||||
AUTIBSP = SystemPAuthFixed | 0x000003E0
|
||||
};
|
||||
|
||||
// Any load or store (including pair).
|
||||
|
@ -318,8 +318,8 @@ void TurboAssembler::Bind(Label* label, BranchTargetIdentifier id) {
|
||||
// instructions between the bind and the target identifier instruction.
|
||||
InstructionAccurateScope scope(this, 1);
|
||||
bind(label);
|
||||
if (id == BranchTargetIdentifier::kPaciasp) {
|
||||
paciasp();
|
||||
if (id == BranchTargetIdentifier::kPacibsp) {
|
||||
pacibsp();
|
||||
} else {
|
||||
bti(id);
|
||||
}
|
||||
@ -1136,7 +1136,7 @@ void TurboAssembler::Push(const CPURegister& src0, const CPURegister& src1,
|
||||
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kSignLR) {
|
||||
Paciasp();
|
||||
Pacibsp();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1153,7 +1153,7 @@ void TurboAssembler::Push(const Register& src0, const VRegister& src1) {
|
||||
DCHECK_IMPLIES((lr_mode == kDontStoreLR), ((src0 != lr) && (src1 != lr)));
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kSignLR) {
|
||||
Paciasp();
|
||||
Pacibsp();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1188,7 +1188,7 @@ void TurboAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1,
|
||||
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kAuthLR) {
|
||||
Autiasp();
|
||||
Autibsp();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1199,7 +1199,7 @@ void TurboAssembler::Poke(const CPURegister& src, const Operand& offset) {
|
||||
DCHECK_IMPLIES((lr_mode == kDontStoreLR), (src != lr));
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kSignLR) {
|
||||
Paciasp();
|
||||
Pacibsp();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1228,7 +1228,7 @@ void TurboAssembler::Peek(const CPURegister& dst, const Operand& offset) {
|
||||
DCHECK_IMPLIES((lr_mode == kDontLoadLR), (dst != lr));
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kAuthLR) {
|
||||
Autiasp();
|
||||
Autibsp();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1238,7 +1238,7 @@ void TurboAssembler::PushCPURegList(CPURegList registers) {
|
||||
DCHECK_IMPLIES((lr_mode == kDontStoreLR), !registers.IncludesAliasOf(lr));
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kSignLR && registers.IncludesAliasOf(lr)) {
|
||||
Paciasp();
|
||||
Pacibsp();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1280,7 +1280,7 @@ void TurboAssembler::PopCPURegList(CPURegList registers) {
|
||||
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
if (lr_mode == kAuthLR && contains_lr) {
|
||||
Autiasp();
|
||||
Autibsp();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1197,7 +1197,7 @@ void MacroAssembler::PeekPair(const CPURegister& dst1, const CPURegister& dst2,
|
||||
|
||||
void MacroAssembler::PushCalleeSavedRegisters() {
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
Paciasp();
|
||||
Pacibsp();
|
||||
#endif
|
||||
|
||||
{
|
||||
@ -1249,7 +1249,7 @@ void MacroAssembler::PopCalleeSavedRegisters() {
|
||||
}
|
||||
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
Autiasp();
|
||||
Autibsp();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1971,7 +1971,7 @@ void TurboAssembler::StoreReturnAddressAndCall(Register target) {
|
||||
Adr(x17, &return_location);
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
Add(x16, sp, kSystemPointerSize);
|
||||
Pacia1716();
|
||||
Pacib1716();
|
||||
#endif
|
||||
Poke(x17, 0);
|
||||
|
||||
@ -3248,7 +3248,7 @@ void TurboAssembler::RestoreFPAndLR() {
|
||||
// We can load the return address directly into x17.
|
||||
Add(x16, fp, StandardFrameConstants::kCallerSPOffset);
|
||||
Ldp(fp, x17, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
Autia1716();
|
||||
Autib1716();
|
||||
Mov(lr, x17);
|
||||
#else
|
||||
Ldp(fp, lr, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
@ -3261,7 +3261,7 @@ void TurboAssembler::StoreReturnAddressInWasmExitFrame(Label* return_location) {
|
||||
Adr(x17, return_location);
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
Add(x16, fp, WasmExitFrameConstants::kCallingPCOffset + kSystemPointerSize);
|
||||
Pacia1716();
|
||||
Pacib1716();
|
||||
#endif
|
||||
Str(x17, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset));
|
||||
}
|
||||
|
@ -503,13 +503,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
void Cbnz(const Register& rt, Label* label);
|
||||
void Cbz(const Register& rt, Label* label);
|
||||
|
||||
void Paciasp() {
|
||||
void Pacibsp() {
|
||||
DCHECK(allow_macro_instructions_);
|
||||
paciasp();
|
||||
pacibsp();
|
||||
}
|
||||
void Autiasp() {
|
||||
void Autibsp() {
|
||||
DCHECK(allow_macro_instructions_);
|
||||
autiasp();
|
||||
autibsp();
|
||||
}
|
||||
|
||||
// The 1716 pac and aut instructions encourage people to use x16 and x17
|
||||
@ -519,7 +519,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
// Register temp = temps.AcquireX(); // temp will be x16
|
||||
// __ Mov(x17, ptr);
|
||||
// __ Mov(x16, modifier); // Will override temp!
|
||||
// __ Pacia1716();
|
||||
// __ Pacib1716();
|
||||
//
|
||||
// To work around this issue, you must exclude x16 and x17 from the scratch
|
||||
// register list. You may need to replace them with other registers:
|
||||
@ -529,18 +529,18 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
// temps.Include(x10, x11);
|
||||
// __ Mov(x17, ptr);
|
||||
// __ Mov(x16, modifier);
|
||||
// __ Pacia1716();
|
||||
void Pacia1716() {
|
||||
// __ Pacib1716();
|
||||
void Pacib1716() {
|
||||
DCHECK(allow_macro_instructions_);
|
||||
DCHECK(!TmpList()->IncludesAliasOf(x16));
|
||||
DCHECK(!TmpList()->IncludesAliasOf(x17));
|
||||
pacia1716();
|
||||
pacib1716();
|
||||
}
|
||||
void Autia1716() {
|
||||
void Autib1716() {
|
||||
DCHECK(allow_macro_instructions_);
|
||||
DCHECK(!TmpList()->IncludesAliasOf(x16));
|
||||
DCHECK(!TmpList()->IncludesAliasOf(x17));
|
||||
autia1716();
|
||||
autib1716();
|
||||
}
|
||||
|
||||
inline void Dmb(BarrierDomain domain, BarrierType type);
|
||||
|
@ -295,7 +295,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
|
||||
FrameDescription::continuation_offset()));
|
||||
__ Ldr(lr, MemOperand(last_output_frame, FrameDescription::pc_offset()));
|
||||
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
|
||||
__ Autiasp();
|
||||
__ Autibsp();
|
||||
#endif
|
||||
__ Br(continuation);
|
||||
}
|
||||
|
@ -1423,10 +1423,10 @@ void DisassemblingDecoder::VisitFPFixedPointConvert(Instruction* instr) {
|
||||
|
||||
// clang-format off
|
||||
#define PAUTH_SYSTEM_MNEMONICS(V) \
|
||||
V(PACIA1716, "pacia1716") \
|
||||
V(AUTIA1716, "autia1716") \
|
||||
V(PACIASP, "paciasp") \
|
||||
V(AUTIASP, "autiasp")
|
||||
V(PACIB1716, "pacib1716") \
|
||||
V(AUTIB1716, "autib1716") \
|
||||
V(PACIBSP, "pacibsp") \
|
||||
V(AUTIBSP, "autibsp")
|
||||
// clang-format on
|
||||
|
||||
void DisassemblingDecoder::VisitSystem(Instruction* instr) {
|
||||
|
@ -10,8 +10,8 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Randomly generated example key for simulating only.
|
||||
const Simulator::PACKey Simulator::kPACKeyIA = {0xc31718727de20f71,
|
||||
0xab9fd4e14b2fec51, 0};
|
||||
const Simulator::PACKey Simulator::kPACKeyIB = {0xeebb163b474e04c8,
|
||||
0x5267ac6fc280fb7c, 1};
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -10,11 +10,6 @@
|
||||
#include "src/common/globals.h"
|
||||
#include "src/execution/arm64/simulator-arm64.h"
|
||||
|
||||
// TODO(v8:10026): Replace hints with instruction aliases, when supported.
|
||||
#define AUTIA1716 "hint #12"
|
||||
#define PACIA1716 "hint #8"
|
||||
#define XPACLRI "hint #7"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -31,13 +26,13 @@ V8_INLINE Address PointerAuthentication::AuthenticatePC(
|
||||
uint64_t sp = reinterpret_cast<uint64_t>(pc_address) + offset_from_sp;
|
||||
uint64_t pc = reinterpret_cast<uint64_t>(*pc_address);
|
||||
#ifdef USE_SIMULATOR
|
||||
pc = Simulator::AuthPAC(pc, sp, Simulator::kPACKeyIA,
|
||||
pc = Simulator::AuthPAC(pc, sp, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
#else
|
||||
asm volatile(
|
||||
" mov x17, %[pc]\n"
|
||||
" mov x16, %[stack_ptr]\n"
|
||||
" " AUTIA1716 "\n"
|
||||
" autib1716\n"
|
||||
" ldr xzr, [x17]\n"
|
||||
" mov %[pc], x17\n"
|
||||
: [pc] "+r"(pc)
|
||||
@ -55,7 +50,7 @@ V8_INLINE Address PointerAuthentication::StripPAC(Address pc) {
|
||||
asm volatile(
|
||||
" mov x16, lr\n"
|
||||
" mov lr, %[pc]\n"
|
||||
" " XPACLRI "\n"
|
||||
" xpaclri\n"
|
||||
" mov %[pc], lr\n"
|
||||
" mov lr, x16\n"
|
||||
: [pc] "+r"(pc)
|
||||
@ -68,13 +63,13 @@ V8_INLINE Address PointerAuthentication::StripPAC(Address pc) {
|
||||
// Sign {pc} using {sp}.
|
||||
V8_INLINE Address PointerAuthentication::SignPCWithSP(Address pc, Address sp) {
|
||||
#ifdef USE_SIMULATOR
|
||||
return Simulator::AddPAC(pc, sp, Simulator::kPACKeyIA,
|
||||
return Simulator::AddPAC(pc, sp, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
#else
|
||||
asm volatile(
|
||||
" mov x17, %[pc]\n"
|
||||
" mov x16, %[sp]\n"
|
||||
" " PACIA1716 "\n"
|
||||
" pacib1716\n"
|
||||
" mov %[pc], x17\n"
|
||||
: [pc] "+r"(pc)
|
||||
: [sp] "r"(sp)
|
||||
@ -92,13 +87,13 @@ V8_INLINE void PointerAuthentication::ReplacePC(Address* pc_address,
|
||||
uint64_t sp = reinterpret_cast<uint64_t>(pc_address) + offset_from_sp;
|
||||
uint64_t old_pc = reinterpret_cast<uint64_t>(*pc_address);
|
||||
#ifdef USE_SIMULATOR
|
||||
uint64_t auth_old_pc = Simulator::AuthPAC(old_pc, sp, Simulator::kPACKeyIA,
|
||||
uint64_t auth_old_pc = Simulator::AuthPAC(old_pc, sp, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
uint64_t raw_old_pc =
|
||||
Simulator::StripPAC(old_pc, Simulator::kInstructionPointer);
|
||||
// Verify that the old address is authenticated.
|
||||
CHECK_EQ(auth_old_pc, raw_old_pc);
|
||||
new_pc = Simulator::AddPAC(new_pc, sp, Simulator::kPACKeyIA,
|
||||
new_pc = Simulator::AddPAC(new_pc, sp, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
#else
|
||||
// Only store newly signed address after we have verified that the old
|
||||
@ -106,10 +101,10 @@ V8_INLINE void PointerAuthentication::ReplacePC(Address* pc_address,
|
||||
asm volatile(
|
||||
" mov x17, %[new_pc]\n"
|
||||
" mov x16, %[sp]\n"
|
||||
" " PACIA1716 "\n"
|
||||
" pacib1716\n"
|
||||
" mov %[new_pc], x17\n"
|
||||
" mov x17, %[old_pc]\n"
|
||||
" " AUTIA1716 "\n"
|
||||
" autib1716\n"
|
||||
" ldr xzr, [x17]\n"
|
||||
: [new_pc] "+&r"(new_pc)
|
||||
: [sp] "r"(sp), [old_pc] "r"(old_pc)
|
||||
@ -127,13 +122,13 @@ V8_INLINE void PointerAuthentication::ReplaceContext(Address* pc_address,
|
||||
uint64_t new_pc;
|
||||
#ifdef USE_SIMULATOR
|
||||
uint64_t auth_pc =
|
||||
Simulator::AuthPAC(old_signed_pc, old_context, Simulator::kPACKeyIA,
|
||||
Simulator::AuthPAC(old_signed_pc, old_context, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
uint64_t raw_pc =
|
||||
Simulator::StripPAC(auth_pc, Simulator::kInstructionPointer);
|
||||
// Verify that the old address is authenticated.
|
||||
CHECK_EQ(raw_pc, auth_pc);
|
||||
new_pc = Simulator::AddPAC(raw_pc, new_context, Simulator::kPACKeyIA,
|
||||
new_pc = Simulator::AddPAC(raw_pc, new_context, Simulator::kPACKeyIB,
|
||||
Simulator::kInstructionPointer);
|
||||
#else
|
||||
// Only store newly signed address after we have verified that the old
|
||||
@ -141,13 +136,13 @@ V8_INLINE void PointerAuthentication::ReplaceContext(Address* pc_address,
|
||||
asm volatile(
|
||||
" mov x17, %[old_pc]\n"
|
||||
" mov x16, %[old_ctx]\n"
|
||||
" " AUTIA1716 "\n"
|
||||
" autib1716\n"
|
||||
" mov x16, %[new_ctx]\n"
|
||||
" " PACIA1716 "\n"
|
||||
" pacib1716\n"
|
||||
" mov %[new_pc], x17\n"
|
||||
" mov x17, %[old_pc]\n"
|
||||
" mov x16, %[old_ctx]\n"
|
||||
" " AUTIA1716 "\n"
|
||||
" autib1716\n"
|
||||
" ldr xzr, [x17]\n"
|
||||
: [new_pc] "=&r"(new_pc)
|
||||
: [old_pc] "r"(old_signed_pc), [old_ctx] "r"(old_context),
|
||||
|
@ -3128,8 +3128,8 @@ bool Simulator::FPProcessNaNs(Instruction* instr) {
|
||||
|
||||
// clang-format off
|
||||
#define PAUTH_SYSTEM_MODES(V) \
|
||||
V(A1716, 17, xreg(16), kPACKeyIA) \
|
||||
V(ASP, 30, xreg(31, Reg31IsStackPointer), kPACKeyIA)
|
||||
V(B1716, 17, xreg(16), kPACKeyIB) \
|
||||
V(BSP, 30, xreg(31, Reg31IsStackPointer), kPACKeyIB)
|
||||
// clang-format on
|
||||
|
||||
void Simulator::VisitSystem(Instruction* instr) {
|
||||
@ -3137,7 +3137,7 @@ void Simulator::VisitSystem(Instruction* instr) {
|
||||
// range of immediates instead of indicating a different instruction. This
|
||||
// makes the decoding tricky.
|
||||
if (instr->Mask(SystemPAuthFMask) == SystemPAuthFixed) {
|
||||
// The BType check for PACIASP happens in CheckBType().
|
||||
// The BType check for PACIBSP happens in CheckBType().
|
||||
switch (instr->Mask(SystemPAuthMask)) {
|
||||
#define DEFINE_PAUTH_FUNCS(SUFFIX, DST, MOD, KEY) \
|
||||
case PACI##SUFFIX: \
|
||||
|
@ -828,8 +828,8 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
|
||||
void CheckBTypeForPAuth() {
|
||||
DCHECK(pc_->IsPAuth());
|
||||
Instr instr = pc_->Mask(SystemPAuthMask);
|
||||
// Only PACI[AB]SP allowed here, but we don't currently support PACIBSP.
|
||||
CHECK_EQ(instr, PACIASP);
|
||||
// Only PACI[AB]SP allowed here, and we only support PACIBSP.
|
||||
CHECK(instr == PACIBSP);
|
||||
// Check BType allows PACI[AB]SP instructions.
|
||||
switch (btype()) {
|
||||
case BranchFromGuardedNotToIP:
|
||||
@ -837,7 +837,7 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
|
||||
// here to be set. This makes PACI[AB]SP behave like "BTI c",
|
||||
// disallowing its execution when BTYPE is BranchFromGuardedNotToIP
|
||||
// (0b11).
|
||||
FATAL("Executing PACIASP with wrong BType.");
|
||||
FATAL("Executing PACIBSP with wrong BType.");
|
||||
case BranchFromUnguardedOrToIP:
|
||||
case BranchAndLink:
|
||||
break;
|
||||
@ -1397,7 +1397,7 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
|
||||
int number;
|
||||
};
|
||||
|
||||
static const PACKey kPACKeyIA;
|
||||
static const PACKey kPACKeyIB;
|
||||
|
||||
// Current implementation is that all pointers are tagged.
|
||||
static bool HasTBI(uint64_t ptr, PointerType type) {
|
||||
|
@ -1878,24 +1878,41 @@ TEST(branch_to_reg) {
|
||||
static void BtiHelper(Register ipreg) {
|
||||
SETUP();
|
||||
|
||||
Label jump_target, jump_call_target, call_target, done;
|
||||
Label jump_target, jump_call_target, call_target, test_pacibsp,
|
||||
pacibsp_target, done;
|
||||
START();
|
||||
UseScratchRegisterScope temps(&masm);
|
||||
temps.Exclude(ipreg);
|
||||
|
||||
__ Adr(x0, &jump_target);
|
||||
__ Br(x0);
|
||||
__ Nop();
|
||||
|
||||
__ Bind(&jump_target, BranchTargetIdentifier::kBtiJump);
|
||||
__ Adr(x0, &call_target);
|
||||
__ Blr(x0);
|
||||
|
||||
__ Adr(ipreg, &jump_call_target);
|
||||
__ Blr(ipreg);
|
||||
__ Adr(lr, &test_pacibsp); // Make Ret return to test_pacibsp.
|
||||
__ Br(ipreg);
|
||||
|
||||
__ Bind(&test_pacibsp, BranchTargetIdentifier::kNone);
|
||||
__ Adr(ipreg, &pacibsp_target);
|
||||
__ Blr(ipreg);
|
||||
__ Adr(lr, &done); // Make Ret return to done label.
|
||||
__ Br(ipreg);
|
||||
|
||||
__ Bind(&call_target, BranchTargetIdentifier::kBtiCall);
|
||||
__ Ret();
|
||||
|
||||
__ Bind(&jump_call_target, BranchTargetIdentifier::kBtiJumpCall);
|
||||
__ Ret();
|
||||
|
||||
__ Bind(&pacibsp_target, BranchTargetIdentifier::kPacibsp);
|
||||
__ Autibsp();
|
||||
__ Ret();
|
||||
|
||||
__ Bind(&done);
|
||||
END();
|
||||
|
||||
@ -11763,12 +11780,12 @@ TEST(system_msr) {
|
||||
CHECK_EQUAL_64(0, x10);
|
||||
}
|
||||
|
||||
TEST(system_pauth_a) {
|
||||
TEST(system_pauth_b) {
|
||||
SETUP();
|
||||
START();
|
||||
|
||||
// Exclude x16 and x17 from the scratch register list so we can use
|
||||
// Pac/Autia1716 safely.
|
||||
// Pac/Autib1716 safely.
|
||||
UseScratchRegisterScope temps(&masm);
|
||||
temps.Exclude(x16, x17);
|
||||
temps.Include(x10, x11);
|
||||
@ -11782,29 +11799,29 @@ TEST(system_pauth_a) {
|
||||
|
||||
// Generate PACs using the 3 system instructions.
|
||||
__ Mov(x17, 0x0000000012345678);
|
||||
__ Pacia1716();
|
||||
__ Pacib1716();
|
||||
__ Mov(x0, x17);
|
||||
|
||||
__ Mov(lr, 0x0000000012345678);
|
||||
__ Paciasp();
|
||||
__ Pacibsp();
|
||||
__ Mov(x2, lr);
|
||||
|
||||
// Authenticate the pointers above.
|
||||
__ Mov(x17, x0);
|
||||
__ Autia1716();
|
||||
__ Autib1716();
|
||||
__ Mov(x3, x17);
|
||||
|
||||
__ Mov(lr, x2);
|
||||
__ Autiasp();
|
||||
__ Autibsp();
|
||||
__ Mov(x5, lr);
|
||||
|
||||
// Attempt to authenticate incorrect pointers.
|
||||
__ Mov(x17, x2);
|
||||
__ Autia1716();
|
||||
__ Autib1716();
|
||||
__ Mov(x6, x17);
|
||||
|
||||
__ Mov(lr, x0);
|
||||
__ Autiasp();
|
||||
__ Autibsp();
|
||||
__ Mov(x8, lr);
|
||||
|
||||
// Restore stack pointer.
|
||||
@ -11830,8 +11847,8 @@ TEST(system_pauth_a) {
|
||||
CHECK_EQUAL_64(0x0000000012345678, x5);
|
||||
|
||||
// Pointers corrupted after failing to authenticate.
|
||||
CHECK_EQUAL_64(0x0020000012345678, x6);
|
||||
CHECK_EQUAL_64(0x0020000012345678, x8);
|
||||
CHECK_EQUAL_64(0x0040000012345678, x6);
|
||||
CHECK_EQUAL_64(0x0040000012345678, x8);
|
||||
|
||||
#endif // USE_SIMULATOR
|
||||
}
|
||||
|
@ -1919,10 +1919,10 @@ TEST_(bti) {
|
||||
TEST(system_pauth) {
|
||||
SET_UP_ASM();
|
||||
|
||||
COMPARE(pacia1716(), "pacia1716");
|
||||
COMPARE(paciasp(), "paciasp");
|
||||
COMPARE(autia1716(), "autia1716");
|
||||
COMPARE(autiasp(), "autiasp");
|
||||
COMPARE(pacib1716(), "pacib1716");
|
||||
COMPARE(pacibsp(), "pacibsp");
|
||||
COMPARE(autib1716(), "autib1716");
|
||||
COMPARE(autibsp(), "autibsp");
|
||||
|
||||
CLEANUP();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user