From: Jeff Dike The patch syscall-security-3 is wrong (provided by me, sorry). I missed, that singlestepping_skas() used to reset PT_DTRACE. This was handled differently in tt and skas. With syscall-security-3 applied, a process in SKAS that singlestepped once continues to singlestep until the next systemcall occurs, even if it is resumed with PTRACE_CONT or PTRACE_SYSCALL. This fix unifies the usage of PT_DTRACE in TT and SKAS. PT_DTRACE now is set by ptrace(PTRACE_SINGLESTEP,...) and reset by singlestepping() and it is evaluated in kern_do_signal(). Signed-off-by: Bodo Stroesser Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton --- 25-akpm/arch/um/kernel/process_kern.c | 8 +++++++- 25-akpm/arch/um/kernel/skas/syscall_kern.c | 1 - 25-akpm/arch/um/kernel/tt/include/tt.h | 1 - 25-akpm/arch/um/kernel/tt/process_kern.c | 7 ------- 25-akpm/arch/um/kernel/tt/syscall_kern.c | 1 - 25-akpm/arch/um/kernel/tt/tracer.c | 1 - 6 files changed, 7 insertions(+), 12 deletions(-) diff -puN arch/um/kernel/process_kern.c~uml-clear-singlestep arch/um/kernel/process_kern.c --- 25/arch/um/kernel/process_kern.c~uml-clear-singlestep 2004-11-04 20:41:41.074767096 -0800 +++ 25-akpm/arch/um/kernel/process_kern.c 2004-11-04 20:41:41.085765424 -0800 @@ -459,9 +459,15 @@ int singlestepping(void * t) { struct task_struct *task = t ? t : current; + if ( ! (task->ptrace & PT_DTRACE) ) + return(0); + + task->ptrace &= ~PT_DTRACE; + if (task->thread.singlestep_syscall) return(0); - return(task->ptrace & PT_DTRACE); + + return 1; } /* diff -puN arch/um/kernel/skas/syscall_kern.c~uml-clear-singlestep arch/um/kernel/skas/syscall_kern.c --- 25/arch/um/kernel/skas/syscall_kern.c~uml-clear-singlestep 2004-11-04 20:41:41.075766944 -0800 +++ 25-akpm/arch/um/kernel/skas/syscall_kern.c 2004-11-04 20:41:41.086765272 -0800 @@ -30,7 +30,6 @@ long execute_syscall_skas(void *r) if(current->thread.singlestep_syscall){ current->thread.singlestep_syscall = 0; - current->ptrace &= ~PT_DTRACE; force_sig(SIGTRAP, current); } diff -puN arch/um/kernel/tt/include/tt.h~uml-clear-singlestep arch/um/kernel/tt/include/tt.h --- 25/arch/um/kernel/tt/include/tt.h~uml-clear-singlestep 2004-11-04 20:41:41.077766640 -0800 +++ 25-akpm/arch/um/kernel/tt/include/tt.h 2004-11-04 20:41:41.086765272 -0800 @@ -24,7 +24,6 @@ extern void set_init_pid(int pid); extern int set_user_mode(void *task); extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); -extern void clear_singlestep(void *t); extern void syscall_handler(int sig, union uml_pt_regs *regs); extern void exit_kernel(int pid, void *task); extern int do_syscall(void *task, int pid, int local_using_sysemu); diff -puN arch/um/kernel/tt/process_kern.c~uml-clear-singlestep arch/um/kernel/tt/process_kern.c --- 25/arch/um/kernel/tt/process_kern.c~uml-clear-singlestep 2004-11-04 20:41:41.079766336 -0800 +++ 25-akpm/arch/um/kernel/tt/process_kern.c 2004-11-04 20:41:41.087765120 -0800 @@ -523,13 +523,6 @@ void set_init_pid(int pid) -err); } -void clear_singlestep(void *t) -{ - struct task_struct *task = t; - - task->ptrace &= ~PT_DTRACE; -} - int start_uml_tt(void) { void *sp; diff -puN arch/um/kernel/tt/syscall_kern.c~uml-clear-singlestep arch/um/kernel/tt/syscall_kern.c --- 25/arch/um/kernel/tt/syscall_kern.c~uml-clear-singlestep 2004-11-04 20:41:41.080766184 -0800 +++ 25-akpm/arch/um/kernel/tt/syscall_kern.c 2004-11-04 20:41:41.087765120 -0800 @@ -125,7 +125,6 @@ long execute_syscall_tt(void *r) if(current->thread.singlestep_syscall){ current->thread.singlestep_syscall = 0; - current->ptrace &= ~PT_DTRACE; force_sig(SIGTRAP, current); } diff -puN arch/um/kernel/tt/tracer.c~uml-clear-singlestep arch/um/kernel/tt/tracer.c --- 25/arch/um/kernel/tt/tracer.c~uml-clear-singlestep 2004-11-04 20:41:41.082765880 -0800 +++ 25-akpm/arch/um/kernel/tt/tracer.c 2004-11-04 20:41:41.088764968 -0800 @@ -336,7 +336,6 @@ int tracer(int (*init_proc)(void *), voi tracing = 0; if(do_syscall(task, pid, local_using_sysemu)) sig = SIGUSR2; - else clear_singlestep(task); break; case SIGPROF: if(tracing) sig = 0; _