Module Name:    src
Committed By:   jmcneill
Date:           Wed Aug 31 22:58:39 UTC 2011

Modified Files:
        src/sys/kern: kern_subr.c sys_process.c
        src/sys/sys: proc.h ptrace.h

Log Message:
PR# kern/45312: ptrace: PT_SETREGS can't alter system calls

Add a new PT_SYSCALLEMU request that cancels the current syscall, for
use with PT_SYSCALL.


To generate a diff of this commit:
cvs rdiff -u -r1.209 -r1.210 src/sys/kern/kern_subr.c
cvs rdiff -u -r1.159 -r1.160 src/sys/kern/sys_process.c
cvs rdiff -u -r1.308 -r1.309 src/sys/sys/proc.h
cvs rdiff -u -r1.42 -r1.43 src/sys/sys/ptrace.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_subr.c
diff -u src/sys/kern/kern_subr.c:1.209 src/sys/kern/kern_subr.c:1.210
--- src/sys/kern/kern_subr.c:1.209	Wed Jul 27 14:35:34 2011
+++ src/sys/kern/kern_subr.c	Wed Aug 31 22:58:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_subr.c,v 1.209 2011/07/27 14:35:34 uebayasi Exp $	*/
+/*	$NetBSD: kern_subr.c,v 1.210 2011/08/31 22:58:39 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.209 2011/07/27 14:35:34 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.210 2011/08/31 22:58:39 jmcneill Exp $");
 
 #include "opt_ddb.h"
 #include "opt_md.h"
@@ -686,6 +686,8 @@
 int
 trace_enter(register_t code, const register_t *args, int narg)
 {
+	int error = 0;
+
 #ifdef SYSCALL_DEBUG
 	scdebug_call(code, args);
 #endif /* SYSCALL_DEBUG */
@@ -694,10 +696,16 @@
 
 #ifdef PTRACE
 	if ((curlwp->l_proc->p_slflag & (PSL_SYSCALL|PSL_TRACED)) ==
-	    (PSL_SYSCALL|PSL_TRACED))
+	    (PSL_SYSCALL|PSL_TRACED)) {
 		process_stoptrace();
+		if (curlwp->l_proc->p_slflag & PSL_SYSCALLEMU) {
+			/* tracer will emulate syscall for us */
+			error = EJUSTRETURN;
+			CLR(curlwp->l_proc->p_slflag, PSL_SYSCALLEMU);
+		}
+	}
 #endif
-	return 0;
+	return error;
 }
 
 /*

Index: src/sys/kern/sys_process.c
diff -u src/sys/kern/sys_process.c:1.159 src/sys/kern/sys_process.c:1.160
--- src/sys/kern/sys_process.c:1.159	Tue Aug 30 22:45:55 2011
+++ src/sys/kern/sys_process.c	Wed Aug 31 22:58:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_process.c,v 1.159 2011/08/30 22:45:55 christos Exp $	*/
+/*	$NetBSD: sys_process.c,v 1.160 2011/08/31 22:58:39 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.159 2011/08/30 22:45:55 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.160 2011/08/31 22:58:39 jmcneill Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_ktrace.h"
@@ -195,6 +195,7 @@
 	case PT_DETACH:
 	case PT_LWPINFO:
 	case PT_SYSCALL:
+	case PT_SYSCALLEMU:
 	case PT_DUMPCORE:
 		result = KAUTH_RESULT_ALLOW;
 		break;
@@ -370,6 +371,7 @@
 	case  PT_DETACH:
 	case  PT_LWPINFO:
 	case  PT_SYSCALL:
+	case  PT_SYSCALLEMU:
 	case  PT_DUMPCORE:
 #ifdef PT_STEP
 	case  PT_STEP:
@@ -453,6 +455,7 @@
 	case PT_DETACH:
 	case PT_KILL:
 	case PT_SYSCALL:
+	case PT_SYSCALLEMU:
 	case PT_ATTACH:
 	case PT_TRACE_ME:
 		pheld = 1;
@@ -714,6 +717,14 @@
 		}
 		break;
 
+	case  PT_SYSCALLEMU:
+		if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) {
+			error = EINVAL;
+			break;
+		}
+		SET(t->p_slflag, PSL_SYSCALLEMU);
+		break;
+
 	case  PT_KILL:
 		/* just send the process a KILL signal. */
 		signo = SIGKILL;

Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.308 src/sys/sys/proc.h:1.309
--- src/sys/sys/proc.h:1.308	Wed Jul 27 13:20:07 2011
+++ src/sys/sys/proc.h	Wed Aug 31 22:58:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: proc.h,v 1.308 2011/07/27 13:20:07 uebayasi Exp $	*/
+/*	$NetBSD: proc.h,v 1.309 2011/08/31 22:58:39 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -378,6 +378,7 @@
 #define	PSL_FSTRACE	0x00010000 /* Debugger process being traced by procfs */
 #define	PSL_CHTRACED	0x00400000 /* Child has been traced & reparented */
 #define	PSL_SYSCALL	0x04000000 /* process has PT_SYSCALL enabled */
+#define	PSL_SYSCALLEMU	0x08000000 /* cancel in-progress syscall */
 
 /*
  * Kept in p_stflag and protected by p_stmutex.

Index: src/sys/sys/ptrace.h
diff -u src/sys/sys/ptrace.h:1.42 src/sys/sys/ptrace.h:1.43
--- src/sys/sys/ptrace.h:1.42	Mon Dec 14 00:48:35 2009
+++ src/sys/sys/ptrace.h	Wed Aug 31 22:58:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.42 2009/12/14 00:48:35 matt Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.43 2011/08/31 22:58:39 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 1984, 1993
@@ -47,6 +47,7 @@
 #define	PT_DUMPCORE	12	/* make the child generate a core dump */
 #define	PT_LWPINFO	13	/* get info about the LWP */
 #define	PT_SYSCALL	14	/* stop on syscall entry/exit */
+#define	PT_SYSCALLEMU	15	/* cancel syscall, tracer will emulate it */
 #define	PT_FIRSTMACH	32	/* for machine-specific requests */
 #include <machine/ptrace.h>	/* machine-specific requests, if any */
 

Reply via email to