From: Jeff Dike <jdike@addtoit.com>

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 <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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;
_