Commit 39758cdf authored by Salome Thirot's avatar Salome Thirot Committed by Commit Bot

[arm64] Fixed authentication bug in liftoff PrepareTailCall

This fixes a bug that made a test fail in mjsunit/wasm/return-call.js
(the CFI bot does not run the tests with --variants=extra, hence why
it didn't catch it).
It also introduces --sim-abort-on-bad-auth, a debug flag for the arm64
simulator that stops a program as soon as an authentication error
appears, to make debugging easier.

Change-Id: Ibee731ab788aff45301d268ef05256b82f5e4613
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2473833
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70601}
parent bf6da74a
......@@ -2101,7 +2101,7 @@ class UseScratchRegisterScope {
#endif
available_->Remove(list);
}
void Include(const Register& reg1, const Register& reg2) {
void Include(const Register& reg1, const Register& reg2 = NoReg) {
CPURegList list(reg1, reg2);
Include(list);
}
......
......@@ -232,6 +232,9 @@ uint64_t Simulator::AuthPAC(uint64_t ptr, uint64_t context, PACKey key,
} else {
int error_lsb = GetTopPACBit(ptr, type) - 2;
uint64_t error_mask = UINT64_C(0x3) << error_lsb;
if (FLAG_sim_abort_on_bad_auth) {
FATAL("Pointer authentication failure.");
}
return (original_ptr & ~error_mask) | (error_code << error_lsb);
}
}
......
......@@ -1408,6 +1408,13 @@ DEFINE_BOOL(log_colour, ENABLE_LOG_COLOUR,
DEFINE_BOOL(trace_sim_messages, false,
"Trace simulator debug messages. Implied by --trace-sim.")
#if defined V8_TARGET_ARCH_ARM64
// pointer-auth-arm64.cc
DEFINE_DEBUG_BOOL(sim_abort_on_bad_auth, false,
"Stop execution when a pointer authentication fails in the "
"ARM64 simulator.")
#endif
// isolate.cc
DEFINE_BOOL(async_stack_traces, true,
"include async stack traces in Error.stack")
......
......@@ -186,25 +186,36 @@ int LiftoffAssembler::PrepareStackFrame() {
void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
int stack_param_delta) {
UseScratchRegisterScope temps(this);
Register scratch = temps.AcquireX();
temps.Exclude(x16, x17);
// This is the previous stack pointer value (before we push the lr and the
// fp). We need to keep it to autenticate the lr and adjust the new stack
// pointer afterwards.
Add(x16, fp, 16);
// Load the fp and lr of the old frame, they will be pushed in the new frame
// during the actual call.
#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
Ldp(fp, x17, MemOperand(fp));
Autib1716();
Mov(lr, x17);
#else
Ldp(fp, lr, MemOperand(fp));
#endif
// Push the return address and frame pointer to complete the stack frame.
sub(sp, sp, 16);
ldr(scratch, MemOperand(fp, 8));
Poke(scratch, 8);
ldr(scratch, MemOperand(fp, 0));
Poke(scratch, 0);
temps.Include(x17);
Register scratch = temps.AcquireX();
// Shift the whole frame upwards.
int slot_count = num_callee_stack_params + 2;
// Shift the whole frame upwards, except for fp and lr.
int slot_count = num_callee_stack_params;
for (int i = slot_count - 1; i >= 0; --i) {
ldr(scratch, MemOperand(sp, i * 8));
str(scratch, MemOperand(fp, (i - stack_param_delta) * 8));
str(scratch, MemOperand(x16, (i - stack_param_delta) * 8));
}
// Set the new stack and frame pointer.
Sub(sp, fp, stack_param_delta * 8);
Pop<kAuthLR>(fp, lr);
// Set the new stack pointer.
Sub(sp, x16, stack_param_delta * 8);
}
void LiftoffAssembler::PatchPrepareStackFrame(int offset, int frame_size) {
......
......@@ -11784,6 +11784,9 @@ TEST(system_msr) {
}
TEST(system_pauth_b) {
#ifdef DEBUG
i::FLAG_sim_abort_on_bad_auth = false;
#endif
SETUP();
START();
......
......@@ -30,6 +30,9 @@ TEST(compute_pac) {
}
TEST(add_and_auth_pac) {
#ifdef DEBUG
i::FLAG_sim_abort_on_bad_auth = false;
#endif
Decoder<DispatchingDecoderVisitor>* decoder =
new Decoder<DispatchingDecoderVisitor>();
Simulator simulator(decoder);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment