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
This commit is contained in:
parent
173acea776
commit
fa4858af26
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user