diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp
index 5ee839a..fec4ca5 100644
a
|
b
|
arch_randomize_stack_pointer(addr_t value)
|
100 | 100 | { |
101 | 101 | STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); |
102 | 102 | value -= random_value() & (B_PAGE_SIZE - 1); |
103 | | return value & ~addr_t(0xf); |
| 103 | return (value & ~addr_t(0xf)) - 8; |
| 104 | // This means, result % 16 == 8, which is what rsp should adhere to |
| 105 | // when a function is entered for the stack to be considered aligned to |
| 106 | // 16 byte. |
104 | 107 | } |
105 | 108 | |
106 | 109 | |
107 | 110 | static uint8* |
108 | | get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action) |
| 111 | get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action, |
| 112 | size_t spaceNeeded) |
109 | 113 | { |
110 | 114 | // Use the alternate signal stack if we should and can. |
111 | 115 | if (thread->signal_stack_enabled |
… |
… |
get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action)
|
114 | 118 | || frame->user_sp >= thread->signal_stack_base |
115 | 119 | + thread->signal_stack_size)) { |
116 | 120 | addr_t stackTop = thread->signal_stack_base + thread->signal_stack_size; |
117 | | return (uint8*)arch_randomize_stack_pointer(stackTop); |
| 121 | return (uint8*)arch_randomize_stack_pointer(stackTop - spaceNeeded); |
118 | 122 | } |
119 | 123 | |
120 | 124 | // We are going to use the stack that we are already on. We must not touch |
121 | 125 | // the red zone (128 byte area below the stack pointer, reserved for use |
122 | 126 | // by functions to store temporary data and guaranteed not to be modified |
123 | 127 | // by signal handlers). |
124 | | return (uint8*)(frame->user_sp - 128); |
| 128 | return (uint8*)((frame->user_sp - 128 - spaceNeeded) & ~addr_t(0xf)) - 8; |
| 129 | // align stack pointer (cf. arch_randomize_stack_pointer()) |
125 | 130 | } |
126 | 131 | |
127 | 132 | |
… |
… |
arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,
|
215 | 220 | void* args2) |
216 | 221 | { |
217 | 222 | addr_t stackTop = thread->user_stack_base + thread->user_stack_size; |
| 223 | addr_t codeAddr; |
218 | 224 | |
219 | 225 | TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, " |
220 | 226 | "stackTop %#lx\n", entry, args1, args2, stackTop); |
221 | 227 | |
222 | | stackTop = arch_randomize_stack_pointer(stackTop); |
| 228 | stackTop = arch_randomize_stack_pointer(stackTop - sizeof(codeAddr)); |
223 | 229 | |
224 | 230 | // Copy the address of the stub that calls exit_thread() when the thread |
225 | 231 | // entry function returns to the top of the stack to act as the return |
226 | 232 | // address. The stub is inside commpage. |
227 | 233 | addr_t commPageAddress = (addr_t)thread->team->commpage_address; |
228 | | addr_t codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] |
| 234 | codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT] |
229 | 235 | + commPageAddress; |
230 | | stackTop -= sizeof(codeAddr); |
231 | 236 | if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) |
232 | 237 | != B_OK) |
233 | 238 | return B_BAD_ADDRESS; |
… |
… |
arch_setup_signal_frame(Thread* thread, struct sigaction* action,
|
324 | 329 | signalFrameData->syscall_restart_return_value = frame->orig_rax; |
325 | 330 | |
326 | 331 | // Get the stack to use and copy the frame data to it. |
327 | | uint8* userStack = get_signal_stack(thread, frame, action); |
| 332 | uint8* userStack = get_signal_stack(thread, frame, action, |
| 333 | sizeof(*signalFrameData) + sizeof(frame->ip)); |
328 | 334 | |
329 | | userStack -= sizeof(*signalFrameData); |
330 | | signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack; |
| 335 | signal_frame_data* userSignalFrameData |
| 336 | = (signal_frame_data*)(userStack + sizeof(frame->ip)); |
331 | 337 | |
332 | 338 | if (user_memcpy(userSignalFrameData, signalFrameData, |
333 | 339 | sizeof(*signalFrameData)) != B_OK) { |
… |
… |
arch_setup_signal_frame(Thread* thread, struct sigaction* action,
|
335 | 341 | } |
336 | 342 | |
337 | 343 | // Copy a return address to the stack so that backtraces will be correct. |
338 | | userStack -= sizeof(frame->ip); |
339 | 344 | if (user_memcpy(userStack, &frame->ip, sizeof(frame->ip)) != B_OK) |
340 | 345 | return B_BAD_ADDRESS; |
341 | 346 | |