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:
@@ -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 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_userspace_thread_exit(void);
|
||||||
void x86_end_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_set_tss_and_kstack(addr_t kstack);
|
||||||
void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg);
|
void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg);
|
||||||
void i386_swap_pgdir(addr_t new_pgdir);
|
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;
|
addr_t stackTop = t->user_stack_base + t->user_stack_size;
|
||||||
uint32 codeSize = (addr_t)x86_end_userspace_thread_exit
|
uint32 codeSize = (addr_t)x86_end_userspace_thread_exit
|
||||||
- (addr_t)x86_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",
|
TRACE(("arch_thread_enter_uspace: entry 0x%lx, args %p %p, ustack_top 0x%lx\n",
|
||||||
entry, args1, args2, stackTop));
|
entry, args1, args2, stackTop));
|
||||||
|
|
||||||
// copy the little stub that calls exit_thread() when the thread entry
|
// 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;
|
stackTop -= codeSize;
|
||||||
|
|
||||||
if (user_memcpy((void *)stackTop, x86_userspace_thread_exit, codeSize) < B_OK)
|
if (user_memcpy((void *)stackTop, x86_userspace_thread_exit, codeSize) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
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();
|
disable_interrupts();
|
||||||
|
|
||||||
i386_set_tss_and_kstack(t->kernel_stack_base + KERNEL_STACK_SIZE);
|
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 the CPU dependent GDT entry for TLS
|
||||||
set_tls_context(t);
|
set_tls_context(t);
|
||||||
|
|
||||||
x86_enter_userspace(entry, args1, args2, stackTop);
|
x86_enter_userspace(entry, stackTop);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
// never gets here
|
// never gets here
|
||||||
|
|||||||
@@ -138,23 +138,16 @@ FUNCTION(x86_userspace_thread_exit):
|
|||||||
FUNCTION(x86_end_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):
|
FUNCTION(x86_enter_userspace):
|
||||||
movl 4(%esp),%eax // get entry point
|
movl 4(%esp), %eax // get entry point
|
||||||
movl 8(%esp),%edx // get arguments
|
movl 8(%esp), %ebx // get user stack
|
||||||
movl 12(%esp),%edi
|
movw $USER_DATA_SEG, %cx
|
||||||
movl 16(%esp),%ebx // get user stack
|
movw %cx, %ds
|
||||||
movw $USER_DATA_SEG,%cx
|
movw %cx, %es
|
||||||
movw %cx,%ds
|
//movw $0x33 + cpu_num, %fs -> fs points to the TLS storage (CPU dependent segment)
|
||||||
movw %cx,%es
|
movw %cx, %gs
|
||||||
//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
|
xorl %ebp, %ebp // this is the last stack frame - we don't need one on return
|
||||||
// (%ebp marks the beginning of this stack frame)
|
// (%ebp marks the beginning of this stack frame)
|
||||||
pushl $USER_DATA_SEG // user data segment
|
pushl $USER_DATA_SEG // user data segment
|
||||||
|
|||||||
Reference in New Issue
Block a user