Ticket #10509: 10509_x86_64.patch

File 10509_x86_64.patch, 3.7 KB (added by korli, 10 years ago)

x86_64 patch

  • src/system/kernel/arch/x86/64/thread.cpp

    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)  
    100100{
    101101    STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1);
    102102    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.
    104107}
    105108
    106109
    107110static uint8*
    108 get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action)
     111get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action,
     112    size_t spaceNeeded)
    109113{
    110114    // Use the alternate signal stack if we should and can.
    111115    if (thread->signal_stack_enabled
    get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action)  
    114118                || frame->user_sp >= thread->signal_stack_base
    115119                    + thread->signal_stack_size)) {
    116120        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);
    118122    }
    119123
    120124    // We are going to use the stack that we are already on. We must not touch
    121125    // the red zone (128 byte area below the stack pointer, reserved for use
    122126    // by functions to store temporary data and guaranteed not to be modified
    123127    // 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())
    125130}
    126131
    127132
    arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,  
    215220    void* args2)
    216221{
    217222    addr_t stackTop = thread->user_stack_base + thread->user_stack_size;
     223    addr_t codeAddr;
    218224
    219225    TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, "
    220226        "stackTop %#lx\n", entry, args1, args2, stackTop);
    221227
    222     stackTop = arch_randomize_stack_pointer(stackTop);
     228    stackTop = arch_randomize_stack_pointer(stackTop - sizeof(codeAddr));
    223229
    224230    // Copy the address of the stub that calls exit_thread() when the thread
    225231    // entry function returns to the top of the stack to act as the return
    226232    // address. The stub is inside commpage.
    227233    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]
    229235        + commPageAddress;
    230     stackTop -= sizeof(codeAddr);
    231236    if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr))
    232237            != B_OK)
    233238        return B_BAD_ADDRESS;
    arch_setup_signal_frame(Thread* thread, struct sigaction* action,  
    324329    signalFrameData->syscall_restart_return_value = frame->orig_rax;
    325330
    326331    // 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));
    328334
    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));
    331337
    332338    if (user_memcpy(userSignalFrameData, signalFrameData,
    333339            sizeof(*signalFrameData)) != B_OK) {
    arch_setup_signal_frame(Thread* thread, struct sigaction* action,  
    335341    }
    336342
    337343    // Copy a return address to the stack so that backtraces will be correct.
    338     userStack -= sizeof(frame->ip);
    339344    if (user_memcpy(userStack, &frame->ip, sizeof(frame->ip)) != B_OK)
    340345        return B_BAD_ADDRESS;
    341346