diff -Naur -X exclude-files ac_cur/arch/um/include/kern_util.h ac/arch/um/include/kern_util.h --- ac_cur/arch/um/include/kern_util.h Sat Sep 15 15:56:11 2001 +++ ac/arch/um/include/kern_util.h Sat Sep 15 20:04:54 2001 @@ -35,7 +35,8 @@ extern int is_stack_fault(unsigned long sp); extern unsigned long segv(unsigned long address, unsigned long ip, int is_write, int is_user); -extern int set_user_thread(void *task, int on, int restore_regs); +extern int set_user_thread(void *task, int on, int restore_regs, + int protect_mem); extern void syscall_ready(void); extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); @@ -120,6 +121,8 @@ extern int config_gdb(char *str); extern int remove_gdb(void); extern char *uml_strdup(char *string); +extern void unprotect_kernel_mem(void); +extern void protect_kernel_mem(void); #endif /* diff -Naur -X exclude-files ac_cur/arch/um/kernel/exec_kern.c ac/arch/um/kernel/exec_kern.c --- ac_cur/arch/um/kernel/exec_kern.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/kernel/exec_kern.c Sat Sep 15 20:04:54 2001 @@ -114,7 +114,7 @@ int um_execve(char *file, char **argv, char **env) { - if(execve1(file, argv, env) == 0) set_user_thread(current, 1, 1); + if(execve1(file, argv, env) == 0) set_user_thread(current, 1, 1, 1); return(-1); } diff -Naur -X exclude-files ac_cur/arch/um/kernel/process_kern.c ac/arch/um/kernel/process_kern.c --- ac_cur/arch/um/kernel/process_kern.c Sat Sep 15 19:23:51 2001 +++ ac/arch/um/kernel/process_kern.c Sat Sep 15 20:06:04 2001 @@ -64,7 +64,7 @@ init_task.thread.extern_pid = pid; } -int set_user_thread(void *t, int on, int restore_regs) +int set_user_thread(void *t, int on, int restore_regs, int protect_mem) { struct task_struct *task; int ret; @@ -75,6 +75,7 @@ ret = task->thread.tracing; task->thread.request.op = on ? OP_TRACE_ON : OP_TRACE_OFF; task->thread.request.u.tracing.restore_regs = restore_regs; + if(on && protect_mem) protect_kernel_mem(); usr1_pid(getpid()); return(ret); } @@ -807,6 +808,26 @@ if(new == NULL) return(NULL); strcpy(new, string); return(new); +} + +void unprotect_kernel_mem(void) +{ + unsigned long start_stack, end_stack; + + start_stack = (unsigned long) current; + end_stack = start_stack + PAGE_SIZE * 4; + protect(physmem, start_stack - physmem, 1, 1, 1); + protect(end_stack, high_physmem - end_stack, 1, 1, 1); +} + +void protect_kernel_mem(void) +{ + unsigned long start_stack, end_stack; + + start_stack = (unsigned long) current; + end_stack = start_stack + PAGE_SIZE * 4; + protect(physmem, start_stack - physmem, 1, 1, 1); + protect(end_stack, high_physmem - end_stack, 1, 1, 1); } /* diff -Naur -X exclude-files ac_cur/arch/um/kernel/syscall_user.c ac/arch/um/kernel/syscall_user.c --- ac_cur/arch/um/kernel/syscall_user.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/kernel/syscall_user.c Sat Sep 15 20:13:58 2001 @@ -65,6 +65,7 @@ int index, syscall, again; kill(getpid(), SIGSTOP); + unprotect_kernel_mem(); timer_ready = 1; syscall_trace(); lock_syscall(); @@ -94,7 +95,7 @@ * This is a race, set_user_thread has to be called with signals off */ timer_ready = 0; - set_user_thread(NULL, 1, 1); + set_user_thread(NULL, 1, 1, 1); return(0); } diff -Naur -X exclude-files ac_cur/arch/um/kernel/trap_user.c ac/arch/um/kernel/trap_user.c --- ac_cur/arch/um/kernel/trap_user.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/kernel/trap_user.c Sat Sep 15 20:04:54 2001 @@ -329,10 +329,11 @@ if(user_mode) interrupt_end(); block_signals(); change_sig(SIGUSR1, 0); - set_user_thread(NULL, user_mode, 0); + set_user_thread(NULL, user_mode, 0, 0); errno = save_errno; if(user_mode) timer_ready = 0; timer_on = save_timer; + if(user_mode) protect_kernel_mem(); } void sig_handler(int sig, struct sigcontext sc) @@ -348,10 +349,11 @@ if(user_mode) interrupt_end(); block_signals(); change_sig(SIGUSR1, 0); - set_user_thread(NULL, user_mode, 0); + set_user_thread(NULL, user_mode, 0, 0); errno = save_errno; if(user_mode) timer_ready = 0; timer_on = save_timer; + if(user_mode) protect_kernel_mem(); } extern int timer_irq_inited, missed_ticks;