Browse Source

Kernel: Add SysV stack alignment to signal trampoline

In both dispatch signal and asm_signal_trampoline we
now ensure that the stack is 16 byte aligned, as per
the System V ABI.
Drew Stratford 6 năm trước cách đây
mục cha
commit
95fe775d81
2 tập tin đã thay đổi với 9 bổ sung2 xóa
  1. 2 1
      Kernel/Process.cpp
  2. 7 1
      Kernel/Thread.cpp

+ 2 - 1
Kernel/Process.cpp

@@ -746,10 +746,11 @@ asm(
     "push ebp\n"
     "push ebp\n"
     "mov ebp, esp\n"
     "mov ebp, esp\n"
     "push eax\n" // we have to store eax 'cause it might be the return value from a syscall
     "push eax\n" // we have to store eax 'cause it might be the return value from a syscall
+    "sub esp, 4\n" // align the stack to 16 bytes
     "mov eax, [ebp+12]\n" // push the signal code
     "mov eax, [ebp+12]\n" // push the signal code
     "push eax\n"
     "push eax\n"
     "call [ebp+8]\n" // call the signal handler
     "call [ebp+8]\n" // call the signal handler
-    "add esp, 4\n"
+    "add esp, 8\n"
     "mov eax, 0x2d\n" // FIXME: We shouldn't be hardcoding this.
     "mov eax, 0x2d\n" // FIXME: We shouldn't be hardcoding this.
     "int 0x82\n" // sigreturn syscall
     "int 0x82\n" // sigreturn syscall
     "asm_signal_trampoline_end:\n"
     "asm_signal_trampoline_end:\n"

+ 7 - 1
Kernel/Thread.cpp

@@ -386,6 +386,12 @@ ShouldUnblockThread Thread::dispatch_signal(u8 signal)
     u32 ret_eip = regs.eip;
     u32 ret_eip = regs.eip;
     u32 ret_eflags = regs.eflags;
     u32 ret_eflags = regs.eflags;
 
 
+    // Align the stack to 16 bytes.
+    // Note that we push 56 bytes (4 * 14) on to the stack,
+    // so we need to account for this here.
+    u32 stack_alignment = (regs.esp_if_crossRing - 56) % 16;
+    regs.esp_if_crossRing -= stack_alignment;
+
     push_value_on_user_stack(regs, ret_eflags);
     push_value_on_user_stack(regs, ret_eflags);
 
 
     push_value_on_user_stack(regs, ret_eip);
     push_value_on_user_stack(regs, ret_eip);
@@ -407,7 +413,7 @@ ShouldUnblockThread Thread::dispatch_signal(u8 signal)
 
 
     regs.eip = g_return_to_ring3_from_signal_trampoline.get();
     regs.eip = g_return_to_ring3_from_signal_trampoline.get();
 
 
-    // FIXME: Should we worry about the stack being 16 byte aligned when entering a signal handler?
+    ASSERT((regs.esp_if_crossRing % 16) == 0);
 
 
     // If we're not blocking we need to update the tss so
     // If we're not blocking we need to update the tss so
     // that the far jump in Scheduler goes to the proper location.
     // that the far jump in Scheduler goes to the proper location.