Ticket #10509: align-stack.diff

File align-stack.diff, 3.5 KB (added by bonefish, 10 years ago)

Implementation suggestion (untested)

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

    diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp
    index a625755..aa9ce0d 100644
    a b arch_randomize_stack_pointer(addr_t value)  
    114114{
    115115    STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1);
    116116    value -= random_value() & (B_PAGE_SIZE - 1);
    117     return value & ~addr_t(0xf);
     117    return (value & ~addr_t(0xf)) - 4;
     118        // This means, result % 16 == 12, which is what esp should adhere to
     119        // when a function is entered for the stack to be considered aligned to
     120        // 16 byte.
    118121}
    119122
    120123
    121124static uint8*
    122 get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action)
     125get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action,
     126    size_t spaceNeeded)
    123127{
    124128    // use the alternate signal stack if we should and can
    125129    if (thread->signal_stack_enabled
    get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action)  
    128132            || frame->user_sp >= thread->signal_stack_base
    129133                + thread->signal_stack_size)) {
    130134        addr_t stackTop = thread->signal_stack_base + thread->signal_stack_size;
    131         return (uint8*)arch_randomize_stack_pointer(stackTop);
     135        return (uint8*)arch_randomize_stack_pointer(stackTop - spaceNeeded);
    132136    }
    133137
    134     return (uint8*)frame->user_sp;
     138    return (uint8*)((frame->user_sp - spaceNeeded) & ~addr_t(0xf)) - 4;
     139        // align stack pointer (cf. arch_randomize_stack_pointer())
    135140}
    136141
    137142
    arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,  
    223228    TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, "
    224229        "ustack_top 0x%lx\n", entry, args1, args2, stackTop));
    225230
    226     stackTop = arch_randomize_stack_pointer(stackTop);
     231    stackTop = arch_randomize_stack_pointer(stackTop - sizeof(args));
    227232
    228233    // Copy the address of the stub that calls exit_thread() when the thread
    229234    // entry function returns to the top of the stack to act as the return
    arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,  
    233238        + commPageAddress;
    234239    args[1] = (uint32)args1;
    235240    args[2] = (uint32)args2;
    236     stackTop -= sizeof(args);
    237241
    238242    if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK)
    239243        return B_BAD_ADDRESS;
    arch_setup_signal_frame(Thread* thread, struct sigaction* action,  
    325329
    326330    // get the stack to use -- that's either the current one or a special signal
    327331    // stack
    328     uint8* userStack = get_signal_stack(thread, frame, action);
     332    uint32 stackFrame[2];
     333    uint8* userStack = get_signal_stack(thread, frame, action,
     334        sizeof(*signalFrameData) + sizeof(stackFrame));
    329335
    330336    // copy the signal frame data onto the stack
    331     userStack -= sizeof(*signalFrameData);
    332     signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack;
     337    signal_frame_data* userSignalFrameData
     338        = (signal_frame_data*)(userStack + sizeof(stackFrame));
    333339    if (user_memcpy(userSignalFrameData, signalFrameData,
    334340            sizeof(*signalFrameData)) != B_OK) {
    335341        return B_BAD_ADDRESS;
    arch_setup_signal_frame(Thread* thread, struct sigaction* action,  
    337343
    338344    // prepare the user stack frame for a function call to the signal handler
    339345    // wrapper function
    340     uint32 stackFrame[2] = {
    341         frame->ip,      // return address
    342         (addr_t)userSignalFrameData, // parameter: pointer to signal frame data
    343     };
     346    stackFrame[0] = frame->ip;
     347    stackFrame[1] = (addr_t)userSignalFrameData;
     348        // parameter: pointer to signal frame data
    344349
    345     userStack -= sizeof(stackFrame);
    346350    if (user_memcpy(userStack, stackFrame, sizeof(stackFrame)) != B_OK)
    347351        return B_BAD_ADDRESS;
    348352