From fa4858af266be4610cb09a91287df56d941433e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 12 Jan 2007 20:40:39 +0000 Subject: [PATCH] Didn't notice that x86_enter_userspace() also copied the thread entry's arguments to the userland stack in an unsafe way - moved that stuff to arch_thread_enter_userspace(), too. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19778 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/x86/arch_cpu.h | 2 +- src/system/kernel/arch/x86/arch_thread.c | 13 ++++++++++-- src/system/kernel/arch/x86/arch_x86.S | 23 ++++++++-------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index ff70e45ab7..8796f690a4 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -102,7 +102,7 @@ void __x86_setup_system_time(uint32 cv_factor); void i386_context_switch(struct arch_thread *old_state, struct arch_thread *new_state, addr_t new_pgdir); void x86_userspace_thread_exit(void); void x86_end_userspace_thread_exit(void); -void x86_enter_userspace(addr_t entry, void *args1, void *args2, addr_t ustack_top); +void x86_enter_userspace(addr_t entry, addr_t stackTop); void i386_set_tss_and_kstack(addr_t kstack); void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); void i386_swap_pgdir(addr_t new_pgdir); diff --git a/src/system/kernel/arch/x86/arch_thread.c b/src/system/kernel/arch/x86/arch_thread.c index e7cead4791..565d82fecd 100644 --- a/src/system/kernel/arch/x86/arch_thread.c +++ b/src/system/kernel/arch/x86/arch_thread.c @@ -312,17 +312,26 @@ arch_thread_enter_userspace(struct thread *t, addr_t entry, void *args1, void *a addr_t stackTop = t->user_stack_base + t->user_stack_size; uint32 codeSize = (addr_t)x86_end_userspace_thread_exit - (addr_t)x86_userspace_thread_exit; + uint32 args[3]; TRACE(("arch_thread_enter_uspace: entry 0x%lx, args %p %p, ustack_top 0x%lx\n", entry, args1, args2, stackTop)); // copy the little stub that calls exit_thread() when the thread entry - // function returns + // function returns, as well as the arguments of the entry function stackTop -= codeSize; if (user_memcpy((void *)stackTop, x86_userspace_thread_exit, codeSize) < B_OK) return B_BAD_ADDRESS; + args[0] = stackTop; + args[1] = (uint32)args1; + args[2] = (uint32)args2; + stackTop -= sizeof(args); + + if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK) + return B_BAD_ADDRESS; + disable_interrupts(); i386_set_tss_and_kstack(t->kernel_stack_base + KERNEL_STACK_SIZE); @@ -330,7 +339,7 @@ arch_thread_enter_userspace(struct thread *t, addr_t entry, void *args1, void *a // set the CPU dependent GDT entry for TLS set_tls_context(t); - x86_enter_userspace(entry, args1, args2, stackTop); + x86_enter_userspace(entry, stackTop); return B_OK; // never gets here diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index ef7741a1dd..71cda78a4d 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -138,23 +138,16 @@ FUNCTION(x86_userspace_thread_exit): FUNCTION(x86_end_userspace_thread_exit): -/* void x86_enter_userspace(addr entry, void *args1, void *args2, addr stackTop); */ +/* void x86_enter_userspace(addr_t entry, addr_t stackTop); */ FUNCTION(x86_enter_userspace): - movl 4(%esp),%eax // get entry point - movl 8(%esp),%edx // get arguments - movl 12(%esp),%edi - movl 16(%esp),%ebx // get user stack - movw $USER_DATA_SEG,%cx - movw %cx,%ds - movw %cx,%es - //movw $0x33 + cpu_num,%fs -> fs points to the TLS storage (CPU dependent segment) - movw %cx,%gs + movl 4(%esp), %eax // get entry point + movl 8(%esp), %ebx // get user stack + movw $USER_DATA_SEG, %cx + movw %cx, %ds + movw %cx, %es + //movw $0x33 + cpu_num, %fs -> fs points to the TLS storage (CPU dependent segment) + movw %cx, %gs - // push the args onto the user stack - movl %edi,-4(%ebx) // args1 - movl %edx,-8(%ebx) // args2 - movl %ebx,-12(%ebx) // fake return address to copied exit stub - sub $12,%ebx xorl %ebp, %ebp // this is the last stack frame - we don't need one on return // (%ebp marks the beginning of this stack frame) pushl $USER_DATA_SEG // user data segment