Module Name:    src
Committed By:   bouyer
Date:           Sat Feb  4 16:58:00 UTC 2012

Modified Files:
        src/sys/arch/amd64/amd64 [netbsd-5]: syscall.c
        src/sys/arch/i386/i386 [netbsd-5]: syscall.c trap.c
        src/sys/kern [netbsd-5]: kern_sig.c kern_sleepq.c kern_subr.c
            sys_process.c
        src/sys/secmodel/bsd44 [netbsd-5]: secmodel_bsd44_suser.c
        src/sys/sys [netbsd-5]: proc.h ptrace.h

Log Message:
Apply patch, requested by jmcneill in ticket #1668:
        sys/arch/amd64/amd64/syscall.c                  patch
        sys/arch/i386/i386/syscall.c                    patch
        sys/arch/i386/i386/trap.c                       patch
        sys/kern/kern_sig.c                             patch
        sys/kern/kern_sleepq.c                          patch
        sys/kern/kern_subr.c                            patch
        sys/kern/sys_process.c                          patch
        sys/secmodel/bsd44/secmodel_bsd44_suser.c       patch
        sys/sys/proc.h                                  patch
        sys/sys/ptrace.h                                patch

arch/i386/i386/machdep.c, arch/amd64/amd64/machdep.c (from
arch/x86/x86/machdep.c) by christos:
Remove code that was used to avoid register spills. setcontext(2) can change
the registers, so re-fetching will produce the wrong result for trace_exit().
arch/i386/i386/trap.c by reinoud:
Fix the illegal instruction return address. It was using the value of the
cpu's %cr2 register but thats not valid:

CR2 Contains a value called Page Fault Linear Address (PFLA). When a page
fault occurs, the address the program attempted to access is stored in the CR2
register.

And this is thus NOT the illegal instruction address!
kern/kern_sig.c by christos:
PR kern/45327: Jared McNeill: ptrace: siginfo doesn't work with traced processes
When saving the signal in p->p_xstat, clear it from the pending mask, but
don't remove it from the siginfo queue, so that next time the debugger
delivers it, the original information is found.
When posting a signal from the debugger l->l_sigpendset is not set, so we
use the process pending signal and add it back to the process pending set.
Split sigget into sigget() and siggetinfo(). When a signal comes from the
debugger (l->l_sigpendset == NULL), using siggetinfo() try to fetch the
siginfo information from l->l_sigpend and then from p->p_sigpend if it
was not found. This allows us to pass siginfo information for traps from
the debugger.
don't delete signal from the debugger.
kern/kern_sleepq.c by christos:
PR kern/40594: Antti Kantee: Don't call issignal() here to determine what errno
to set for the interrupted syscall, because issignal() will consume the signal
and it will not be delivered to the process afterwards. Instead call
sigispending() (which now returns the first pending signal) and does not
consume the signal.
We need to process SA_STOP signals immediately, and not deliver them to
the process. Instead of re-structuring the code to do that, call issignal()
like before in that case. (tail -F /file^Zfg should not get interrupted).
kern/kern_subr.c by jmcneill, christos:
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.
For PT_SYSCALLEMU, no need to stop again on syscall exit.
ifdef unused variable with -UPTRACE

kern/sys_process.c, sys/proc.h, sys/ptrace.h, 
secmodel/bsd44/secmodel_bsd44_suser.c by jmcneill, christos:
PR kern/43681: PT_SYSCALL appears to be broken

sys_ptrace: For PT_CONTINUE/PT_SYSCALL/PT_DETACH, modify the p_trace_enabled
flag of the target process, not the calling process.
Process the signal now, otherwise calling issignal() and ignoring
the return will lose the signal if it came from the debugger
(issignal() clears p->p_xstat)
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.
PR kern/45330: ptrace: signals can alter syscall return values

process_stoptrace: defer signal processing to userret, ok christos@


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.44.4.1 src/sys/arch/amd64/amd64/syscall.c
cvs rdiff -u -r1.57 -r1.57.4.1 src/sys/arch/i386/i386/syscall.c
cvs rdiff -u -r1.241.4.3 -r1.241.4.4 src/sys/arch/i386/i386/trap.c
cvs rdiff -u -r1.289.4.6 -r1.289.4.7 src/sys/kern/kern_sig.c
cvs rdiff -u -r1.35 -r1.35.4.1 src/sys/kern/kern_sleepq.c
cvs rdiff -u -r1.192.4.1 -r1.192.4.2 src/sys/kern/kern_subr.c
cvs rdiff -u -r1.143.4.1 -r1.143.4.2 src/sys/kern/sys_process.c
cvs rdiff -u -r1.59 -r1.59.4.1 src/sys/secmodel/bsd44/secmodel_bsd44_suser.c
cvs rdiff -u -r1.282 -r1.282.4.1 src/sys/sys/proc.h
cvs rdiff -u -r1.40 -r1.40.20.1 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/arch/amd64/amd64/syscall.c
diff -u src/sys/arch/amd64/amd64/syscall.c:1.44 src/sys/arch/amd64/amd64/syscall.c:1.44.4.1
--- src/sys/arch/amd64/amd64/syscall.c:1.44	Tue Oct 21 12:16:59 2008
+++ src/sys/arch/amd64/amd64/syscall.c	Sat Feb  4 16:57:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: syscall.c,v 1.44 2008/10/21 12:16:59 ad Exp $	*/
+/*	$NetBSD: syscall.c,v 1.44.4.1 2012/02/04 16:57:58 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.44 2008/10/21 12:16:59 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.44.4.1 2012/02/04 16:57:58 bouyer Exp $");
 
 #include "opt_sa.h"
 
@@ -121,8 +121,6 @@ syscall(struct trapframe *frame)
 		    &frame->tf_arg6, callp->sy_argsize - 6 * 8);
 		if (error != 0)
 			goto bad;
-		/* Refetch to avoid register spill to stack */
-		code = frame->tf_rax & (SYS_NSYSENT - 1);
 	}
 
 	if (!__predict_false(p->p_trace_enabled)
@@ -135,7 +133,6 @@ syscall(struct trapframe *frame)
 
 	if (__predict_false(p->p_trace_enabled)
 	    && !__predict_false(callp->sy_flags & SYCALL_INDIRECT)) {
-		code = frame->tf_rax & (SYS_NSYSENT - 1);
 		trace_exit(code, rval, error);
 	}
 

Index: src/sys/arch/i386/i386/syscall.c
diff -u src/sys/arch/i386/i386/syscall.c:1.57 src/sys/arch/i386/i386/syscall.c:1.57.4.1
--- src/sys/arch/i386/i386/syscall.c:1.57	Tue Oct 21 12:16:59 2008
+++ src/sys/arch/i386/i386/syscall.c	Sat Feb  4 16:57:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: syscall.c,v 1.57 2008/10/21 12:16:59 ad Exp $	*/
+/*	$NetBSD: syscall.c,v 1.57.4.1 2012/02/04 16:57:58 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.57 2008/10/21 12:16:59 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.57.4.1 2012/02/04 16:57:58 bouyer Exp $");
 
 #include "opt_vm86.h"
 #include "opt_sa.h"
@@ -114,7 +114,6 @@ syscall(struct trapframe *frame)
 
 	if (__predict_false(l->l_proc->p_trace_enabled)
 	    && !__predict_false(callp->sy_flags & SYCALL_INDIRECT)) {
-		code = frame->tf_eax & (SYS_NSYSENT - 1);
 		trace_exit(code, rval, error);
 	}
 

Index: src/sys/arch/i386/i386/trap.c
diff -u src/sys/arch/i386/i386/trap.c:1.241.4.3 src/sys/arch/i386/i386/trap.c:1.241.4.4
--- src/sys/arch/i386/i386/trap.c:1.241.4.3	Fri Jul 16 18:40:39 2010
+++ src/sys/arch/i386/i386/trap.c	Sat Feb  4 16:57:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.241.4.3 2010/07/16 18:40:39 riz Exp $	*/
+/*	$NetBSD: trap.c,v 1.241.4.4 2012/02/04 16:57:58 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.241.4.3 2010/07/16 18:40:39 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.241.4.4 2012/02/04 16:57:58 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -529,7 +529,7 @@ kern_pagefault:
 	case T_FPOPFLT|T_USER:		/* coprocessor operand fault */
 		KSI_INIT_TRAP(&ksi);
 		ksi.ksi_signo = SIGILL;
-		ksi.ksi_addr = (void *)rcr2();
+		ksi.ksi_addr = (void *)frame->tf_eip;
 		switch (type) {
 		case T_PRIVINFLT|T_USER:
 			ksi.ksi_code = ILL_PRVOPC;

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.289.4.6 src/sys/kern/kern_sig.c:1.289.4.7
--- src/sys/kern/kern_sig.c:1.289.4.6	Sat Jan 16 17:32:52 2010
+++ src/sys/kern/kern_sig.c	Sat Feb  4 16:57:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.289.4.6 2010/01/16 17:32:52 bouyer Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.289.4.7 2012/02/04 16:57:58 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.289.4.6 2010/01/16 17:32:52 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.289.4.7 2012/02/04 16:57:58 bouyer Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_compat_sunos.h"
@@ -475,6 +475,40 @@ ksiginfo_queue_drain0(ksiginfoq_t *kq)
 	}
 }
 
+static bool
+siggetinfo(sigpend_t *sp, ksiginfo_t *out, int signo)
+{
+	ksiginfo_t *ksi;
+
+	if (sp == NULL)
+		goto out;
+
+	/* Find siginfo and copy it out. */
+	CIRCLEQ_FOREACH(ksi, &sp->sp_info, ksi_list) {
+		if (ksi->ksi_signo != signo)
+			continue;
+		CIRCLEQ_REMOVE(&sp->sp_info, ksi, ksi_list);
+		KASSERT((ksi->ksi_flags & KSI_FROMPOOL) != 0);
+		KASSERT((ksi->ksi_flags & KSI_QUEUED) != 0);
+		ksi->ksi_flags &= ~KSI_QUEUED;
+		if (out != NULL) {
+			memcpy(out, ksi, sizeof(*out));
+			out->ksi_flags &= ~(KSI_FROMPOOL | KSI_QUEUED);
+		}
+		ksiginfo_free(ksi);	/* XXXSMP */
+		return true;
+	}
+
+out:
+	/* If there is no siginfo, then manufacture it. */
+	if (out != NULL) {
+		KSI_INIT(out);
+		out->ksi_info._signo = signo;
+		out->ksi_info._code = SI_NOINFO;
+	}
+	return false;
+}
+
 /*
  * sigget:
  *
@@ -485,7 +519,6 @@ ksiginfo_queue_drain0(ksiginfoq_t *kq)
 int
 sigget(sigpend_t *sp, ksiginfo_t *out, int signo, const sigset_t *mask)
 {
-        ksiginfo_t *ksi;
 	sigset_t tset;
 
 	/* If there's no pending set, the signal is from the debugger. */
@@ -508,30 +541,8 @@ sigget(sigpend_t *sp, ksiginfo_t *out, i
 	}
 
 	sigdelset(&sp->sp_set, signo);
-
-	/* Find siginfo and copy it out. */
-	CIRCLEQ_FOREACH(ksi, &sp->sp_info, ksi_list) {
-		if (ksi->ksi_signo == signo) {
-			CIRCLEQ_REMOVE(&sp->sp_info, ksi, ksi_list);
-			KASSERT((ksi->ksi_flags & KSI_FROMPOOL) != 0);
-			KASSERT((ksi->ksi_flags & KSI_QUEUED) != 0);
-			ksi->ksi_flags &= ~KSI_QUEUED;
-			if (out != NULL) {
-				memcpy(out, ksi, sizeof(*out));
-				out->ksi_flags &= ~(KSI_FROMPOOL | KSI_QUEUED);
-			}
-			ksiginfo_free(ksi);
-			return signo;
-		}
-	}
-
 out:
-	/* If there's no siginfo, then manufacture it. */
-	if (out != NULL) {
-		KSI_INIT(out);
-		out->ksi_info._signo = signo;
-		out->ksi_info._code = SI_NOINFO;
-	}
+	(void)siggetinfo(sp, out, signo);
 
 	return signo;
 }
@@ -626,10 +637,10 @@ sigclearall(struct proc *p, const sigset
 /*
  * sigispending:
  *
- *	Return true if there are pending signals for the current LWP.  May
- *	be called unlocked provided that LW_PENDSIG is set, and that the
- *	signal has been posted to the appopriate queue before LW_PENDSIG is
- *	set.
+ *	Return the first signal number if there are pending signals for the
+ *	current LWP.  May be called unlocked provided that LW_PENDSIG is set,
+ *	and that the signal has been posted to the appopriate queue before
+ *	LW_PENDSIG is set.
  */ 
 int
 sigispending(struct lwp *l, int signo)
@@ -645,10 +656,10 @@ sigispending(struct lwp *l, int signo)
 	sigminusset(&l->l_sigmask, &tset);
 
 	if (signo == 0) {
-		if (firstsig(&tset) != 0)
-			return EINTR;
+		if ((signo = firstsig(&tset)) != 0)
+			return signo;
 	} else if (sigismember(&tset, signo))
-		return EINTR;
+		return signo;
 
 	return 0;
 }
@@ -1716,8 +1727,9 @@ issignal(struct lwp *l)
 
 	for (;;) {
 		/* Discard any signals that we have decided not to take. */
-		if (signo != 0)
+		if (signo != 0) {
 			(void)sigget(sp, NULL, signo, NULL);
+		}
 
 		/* Bail out if we do not own the virtual processor */
 		if (l->l_flag & LW_SA && l->l_savp->savp_lwp != l)
@@ -1787,8 +1799,13 @@ issignal(struct lwp *l)
 		 */
 		if ((p->p_slflag & PSL_TRACED) != 0 &&
 		    (p->p_lflag & PL_PPWAIT) == 0 && signo != SIGKILL) {
-			/* Take the signal. */
-			(void)sigget(sp, NULL, signo, NULL);
+			/*
+			 * Take the signal, but don't remove it from the
+			 * siginfo queue, because the debugger can send
+			 * it later.
+			 */
+			if (sp)
+				sigdelset(&sp->sp_set, signo);
 			p->p_xstat = signo;
 
 			/* Emulation-specific handling of signal trace */
@@ -1926,7 +1943,12 @@ postsig(int signo)
 	 */
 	action = SIGACTION_PS(ps, signo).sa_handler;
 	l->l_ru.ru_nsignals++;
-	sigget(l->l_sigpendset, &ksi, signo, NULL);
+	if (l->l_sigpendset == NULL) {
+		/* From the debugger */
+		if (!siggetinfo(&l->l_sigpend, &ksi, signo))
+			(void)siggetinfo(&p->p_sigpend, &ksi, signo);
+	} else
+		sigget(l->l_sigpendset, &ksi, signo, NULL);
 
 	if (ktrpoint(KTR_PSIG)) {
 		mutex_exit(p->p_lock);

Index: src/sys/kern/kern_sleepq.c
diff -u src/sys/kern/kern_sleepq.c:1.35 src/sys/kern/kern_sleepq.c:1.35.4.1
--- src/sys/kern/kern_sleepq.c:1.35	Wed Oct 15 06:51:20 2008
+++ src/sys/kern/kern_sleepq.c	Sat Feb  4 16:57:58 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sleepq.c,v 1.35 2008/10/15 06:51:20 wrstuden Exp $	*/
+/*	$NetBSD: kern_sleepq.c,v 1.35.4.1 2012/02/04 16:57:58 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.35 2008/10/15 06:51:20 wrstuden Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.35.4.1 2012/02/04 16:57:58 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -292,7 +292,9 @@ sleepq_block(int timo, bool catch)
 			 * not recurse again.
 			 */
 			mutex_enter(p->p_lock);
-			if ((sig = issignal(l)) != 0)
+			if (((sig = sigispending(l, 0)) != 0 &&
+			    (sigprop[sig] & SA_STOP) == 0) ||
+			    (sig = issignal(l)) != 0)
 				error = sleepq_sigtoerror(l, sig);
 			mutex_exit(p->p_lock);
 		}

Index: src/sys/kern/kern_subr.c
diff -u src/sys/kern/kern_subr.c:1.192.4.1 src/sys/kern/kern_subr.c:1.192.4.2
--- src/sys/kern/kern_subr.c:1.192.4.1	Mon Nov 17 18:56:05 2008
+++ src/sys/kern/kern_subr.c	Sat Feb  4 16:57:59 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_subr.c,v 1.192.4.1 2008/11/17 18:56:05 snj Exp $	*/
+/*	$NetBSD: kern_subr.c,v 1.192.4.2 2012/02/04 16:57:59 bouyer 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.192.4.1 2008/11/17 18:56:05 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.192.4.2 2012/02/04 16:57:59 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_md.h"
@@ -1306,6 +1306,8 @@ trace_is_enabled(struct proc *p)
 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 */
@@ -1314,10 +1316,15 @@ trace_enter(register_t code, const regis
 
 #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;
+		}
+	}
 #endif
-	return 0;
+	return error;
 }
 
 /*
@@ -1330,6 +1337,10 @@ trace_enter(register_t code, const regis
 void
 trace_exit(register_t code, register_t rval[], int error)
 {
+#ifdef PTRACE
+	struct proc *p = curlwp->l_proc;
+#endif
+
 #ifdef SYSCALL_DEBUG
 	scdebug_ret(code, error, rval);
 #endif /* SYSCALL_DEBUG */
@@ -1337,8 +1348,9 @@ trace_exit(register_t code, register_t r
 	ktrsysret(code, error, rval);
 	
 #ifdef PTRACE
-	if ((curlwp->l_proc->p_slflag & (PSL_SYSCALL|PSL_TRACED)) ==
+	if ((p->p_slflag & (PSL_SYSCALL|PSL_TRACED|PSL_SYSCALLEMU)) ==
 	    (PSL_SYSCALL|PSL_TRACED))
 		process_stoptrace();
+	CLR(p->p_slflag, PSL_SYSCALLEMU);
 #endif
 }

Index: src/sys/kern/sys_process.c
diff -u src/sys/kern/sys_process.c:1.143.4.1 src/sys/kern/sys_process.c:1.143.4.2
--- src/sys/kern/sys_process.c:1.143.4.1	Fri Feb  6 01:54:09 2009
+++ src/sys/kern/sys_process.c	Sat Feb  4 16:57:59 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_process.c,v 1.143.4.1 2009/02/06 01:54:09 snj Exp $	*/
+/*	$NetBSD: sys_process.c,v 1.143.4.2 2012/02/04 16:57:59 bouyer 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.143.4.1 2009/02/06 01:54:09 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.143.4.2 2012/02/04 16:57:59 bouyer Exp $");
 
 #include "opt_coredump.h"
 #include "opt_ptrace.h"
@@ -294,6 +294,7 @@ sys_ptrace(struct lwp *l, const struct s
 	case  PT_DETACH:
 	case  PT_LWPINFO:
 	case  PT_SYSCALL:
+	case  PT_SYSCALLEMU:
 #ifdef COREDUMP
 	case  PT_DUMPCORE:
 #endif
@@ -378,6 +379,7 @@ sys_ptrace(struct lwp *l, const struct s
 	case PT_DETACH:
 	case PT_KILL:
 	case PT_SYSCALL:
+	case PT_SYSCALLEMU:
 	case PT_ATTACH:
 	case PT_TRACE_ME:
 		pheld = 1;
@@ -525,7 +527,7 @@ sys_ptrace(struct lwp *l, const struct s
 #endif
 			}
 		}
-		p->p_trace_enabled = trace_is_enabled(p);
+		t->p_trace_enabled = trace_is_enabled(t);
 
 		/*
 		 * From the 4.4BSD PRM:
@@ -598,6 +600,14 @@ sys_ptrace(struct lwp *l, const struct s
 		}
 		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;
@@ -951,14 +961,11 @@ process_stoptrace(void)
 	proc_stop(p, 1, SIGSTOP);
 	mutex_exit(proc_lock);
 
-	/*
-	 * Call issignal() once only, to have it take care of the
-	 * pending stop.  Signal processing will take place as usual
-	 * from userret().
-	 */
-	KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
-	(void)issignal(l);
+	if (sigispending(l, 0)) {
+		lwp_lock(l);
+		l->l_flag |= LW_PENDSIG;
+		lwp_unlock(l);
+	}
 	mutex_exit(p->p_lock);
-	KERNEL_LOCK(l->l_biglocks, l);
 }
 #endif	/* KTRACE || PTRACE */

Index: src/sys/secmodel/bsd44/secmodel_bsd44_suser.c
diff -u src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.59 src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.59.4.1
--- src/sys/secmodel/bsd44/secmodel_bsd44_suser.c:1.59	Wed Oct 22 11:16:29 2008
+++ src/sys/secmodel/bsd44/secmodel_bsd44_suser.c	Sat Feb  4 16:57:59 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_bsd44_suser.c,v 1.59 2008/10/22 11:16:29 ad Exp $ */
+/* $NetBSD: secmodel_bsd44_suser.c,v 1.59.4.1 2012/02/04 16:57:59 bouyer Exp $ */
 /*-
  * Copyright (c) 2006 Elad Efrat <e...@netbsd.org>
  * All rights reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.59 2008/10/22 11:16:29 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_bsd44_suser.c,v 1.59.4.1 2012/02/04 16:57:59 bouyer Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -589,6 +589,7 @@ secmodel_bsd44_suser_process_cb(kauth_cr
 		case PT_DETACH:
 		case PT_LWPINFO:
 		case PT_SYSCALL:
+		case PT_SYSCALLEMU:
 		case PT_DUMPCORE:
 			result = KAUTH_RESULT_ALLOW;
 			break;

Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.282 src/sys/sys/proc.h:1.282.4.1
--- src/sys/sys/proc.h:1.282	Wed Oct 22 11:14:33 2008
+++ src/sys/sys/proc.h	Sat Feb  4 16:57:59 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: proc.h,v 1.282 2008/10/22 11:14:33 ad Exp $	*/
+/*	$NetBSD: proc.h,v 1.282.4.1 2012/02/04 16:57:59 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -382,6 +382,7 @@ struct proc {
 #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.40 src/sys/sys/ptrace.h:1.40.20.1
--- src/sys/sys/ptrace.h:1.40	Sat Jan  5 12:41:43 2008
+++ src/sys/sys/ptrace.h	Sat Feb  4 16:57:59 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.40 2008/01/05 12:41:43 dsl Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.40.20.1 2012/02/04 16:57:59 bouyer 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