Commit 9fd2c27f authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [builtins] Clear c_entry_fp when entering JS and at exception path

Port 07b03b83

Original Commit Message:

    c_entry_fp is normally cleared in `LeaveExitFrame`, but we adjust
    the frame without it in the exception path.

    This can cause the SafeStackFrameIterator to assume we have an exit
    frame and iterate over frames incorrectly, which for arm64 can
    cause pointer authentication failures with CFI enabled. Even without
    the pointer authentication failure, we iterate over frames
incorrectly,
    so make this change for other architectures too.

    Also clear c_entry_fp in the beginning of JSEntry, after pushing it
    on the stack. Not doing this doesn't cause pointer authentication
    failures, but it will make the SafeStackFrameIterator assume we
    are executing C++ and miss the JS frames on top.

R=georgia.kouveli@arm.com, joransiu@ca.ibm.com, junyan@redhat.com,
midawson@redhat.com, mfarazma@redhat.com
BUG=
LOG=N

Change-Id: Id12286a0f18fce928f9e44825fc13cd0338bac46
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2665893Reviewed-by: 's avatarMilad Fa <mfarazma@redhat.com>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/master@{#72466}
parent 6d3a53e7
......@@ -554,6 +554,13 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
__ LoadP(r0, MemOperand(r3));
__ push(r0);
// Clear c_entry_fp, now we've pushed its previous value to the stack.
// If the c_entry_fp is not already zero and we don't clear it, the
// SafeStackFrameIterator will assume we are executing C++ and miss the JS
// frames on top.
__ li(r0, Operand::Zero());
__ StoreP(r0, MemOperand(r3));
Register scratch = r9;
// Set up frame pointer for the frame to be pushed.
__ addi(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
......@@ -2598,6 +2605,15 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// underlying register is caller-saved and can be arbitrarily clobbered.
__ ResetSpeculationPoisonRegister();
// Clear c_entry_fp, like we do in `LeaveExitFrame`.
{
UseScratchRegisterScope temps(masm);
__ Move(ip, ExternalReference::Create(IsolateAddressId::kCEntryFPAddress,
masm->isolate()));
__ mov(r0, Operand::Zero());
__ StoreP(r0, MemOperand(ip));
}
// Compute the handler entry address and jump to it.
ConstantPoolUnavailableScope constant_pool_unavailable(masm);
__ Move(ip, pending_handler_entrypoint_address);
......
......@@ -548,7 +548,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
}
// save r6 to r1
__ mov(r1, r6);
__ mov(r0, r6);
// Push a frame with special values setup to mark it as an entry frame.
// Bad FP (-1)
......@@ -565,11 +565,18 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
__ mov(r8, Operand(StackFrame::TypeToMarker(type)));
__ mov(r7, Operand(StackFrame::TypeToMarker(type)));
// Save copies of the top frame descriptor on the stack.
__ Move(r6, ExternalReference::Create(
IsolateAddressId::kCEntryFPAddress, masm->isolate()));
__ LoadU64(r6, MemOperand(r6));
__ Move(r1, ExternalReference::Create(IsolateAddressId::kCEntryFPAddress,
masm->isolate()));
__ LoadU64(r6, MemOperand(r1));
__ StoreMultipleP(r6, r9, MemOperand(sp, kSystemPointerSize));
// Clear c_entry_fp, now we've pushed its previous value to the stack.
// If the c_entry_fp is not already zero and we don't clear it, the
// SafeStackFrameIterator will assume we are executing C++ and miss the JS
// frames on top.
__ mov(r6, Operand::Zero());
__ StoreU64(r6, MemOperand(r1));
Register scrach = r8;
// Set up frame pointer for the frame to be pushed.
......@@ -581,7 +588,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
EntryFrameConstants::kCallerFPOffset - kSystemPointerSize;
// restore r6
__ mov(r6, r1);
__ mov(r6, r0);
// If this is the outermost JS call, set js_entry_sp value.
Label non_outermost_js;
......@@ -2652,6 +2659,15 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// underlying register is caller-saved and can be arbitrarily clobbered.
__ ResetSpeculationPoisonRegister();
// Clear c_entry_fp, like we do in `LeaveExitFrame`.
{
UseScratchRegisterScope temps(masm);
__ Move(r1, ExternalReference::Create(IsolateAddressId::kCEntryFPAddress,
masm->isolate()));
__ mov(r0, Operand::Zero());
__ StoreU64(r0, MemOperand(r1));
}
// Compute the handler entry address and jump to it.
__ Move(r3, pending_handler_entrypoint_address);
__ LoadU64(r3, MemOperand(r3));
......
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