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 */