Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Correct handling of corner cases in fork1(9) code u...
details: https://anonhg.NetBSD.org/src/rev/537b30459b3f
branches: trunk
changeset: 456293:537b30459b3f
user: kamil <kamil%NetBSD.org@localhost>
date: Wed May 01 18:01:54 2019 +0000
description:
Correct handling of corner cases in fork1(9) code under a debugger
Correct detaching and SIGKILLing forker and vforker in the middle of its
operation.
diffstat:
sys/kern/kern_fork.c | 48 ++++++++++++++++++++++++++++++++++--------------
sys/kern/kern_sig.c | 13 +++++++++++--
2 files changed, 45 insertions(+), 16 deletions(-)
diffs (135 lines):
diff -r a192f17783c3 -r 537b30459b3f sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c Wed May 01 17:21:55 2019 +0000
+++ b/sys/kern/kern_fork.c Wed May 01 18:01:54 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_fork.c,v 1.210 2019/05/01 17:21:55 kamil Exp $ */
+/* $NetBSD: kern_fork.c,v 1.211 2019/05/01 18:01:54 kamil Exp $ */
/*-
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.210 2019/05/01 17:21:55 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.211 2019/05/01 18:01:54 kamil Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@@ -203,6 +203,30 @@
*/
static struct timeval fork_tfmrate = { 10, 0 };
+static inline bool
+tracefork(struct proc *p, int flags)
+{
+
+ return (p->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) ==
+ (PSL_TRACEFORK|PSL_TRACED) && (flags & FORK_PPWAIT) == 0;
+}
+
+static inline bool
+tracevfork(struct proc *p, int flags)
+{
+
+ return (p->p_slflag & (PSL_TRACEVFORK|PSL_TRACED)) ==
+ (PSL_TRACEVFORK|PSL_TRACED) && (flags & FORK_PPWAIT) != 0;
+}
+
+static inline bool
+tracevforkdone(struct proc *p, int flags)
+{
+
+ return (p->p_slflag & (PSL_TRACEVFORK_DONE|PSL_TRACED)) ==
+ (PSL_TRACEVFORK_DONE|PSL_TRACED) && (flags & FORK_PPWAIT);
+}
+
/*
* General fork call. Note that another LWP in the process may call exec()
* or exit() while we are forking. It's safe to continue here, because
@@ -219,7 +243,7 @@
int count;
vaddr_t uaddr;
int tnprocs;
- int tracefork, tracevfork, tracevforkdone;
+ bool trace_fork, trace_vfork;
int error = 0;
p1 = l1->l_proc;
@@ -477,19 +501,15 @@
/*
* Trace fork(2) and vfork(2)-like events on demand in a debugger.
*/
- tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) ==
- (PSL_TRACEFORK|PSL_TRACED) && (flags & FORK_PPWAIT) == 0;
- tracevfork = (p1->p_slflag & (PSL_TRACEVFORK|PSL_TRACED)) ==
- (PSL_TRACEVFORK|PSL_TRACED) && (flags & FORK_PPWAIT) != 0;
- tracevforkdone = (p1->p_slflag & (PSL_TRACEVFORK_DONE|PSL_TRACED)) ==
- (PSL_TRACEVFORK_DONE|PSL_TRACED) && (flags & FORK_PPWAIT);
- if (tracefork || tracevfork)
+ trace_fork = tracefork(p1, flags);
+ trace_vfork = tracevfork(p1, flags);
+ if (trace_fork || trace_vfork)
proc_changeparent(p2, p1->p_pptr);
- if (tracefork) {
+ if (trace_fork) {
p1->p_fpid = p2->p_pid;
p2->p_fpid = p1->p_pid;
}
- if (tracevfork) {
+ if (trace_vfork) {
p1->p_vfpid = p2->p_pid;
p2->p_vfpid = p1->p_pid;
}
@@ -573,7 +593,7 @@
/*
* Let the parent know that we are tracing its child.
*/
- if (tracefork || tracevfork) {
+ if (tracefork(p1, flags) || tracevfork(p1, flags)) {
mutex_enter(p1->p_lock);
eventswitch(SIGTRAP, TRAP_CHLD);
// XXX ktrpoint(KTR_PSIG)
@@ -591,7 +611,7 @@
/*
* Let the parent know that we are tracing its child.
*/
- if (tracevforkdone) {
+ if (tracevforkdone(p1, flags)) {
mutex_enter(p1->p_lock);
p1->p_vfpid_done = retval[0];
eventswitch(SIGTRAP, TRAP_CHLD);
diff -r a192f17783c3 -r 537b30459b3f sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c Wed May 01 17:21:55 2019 +0000
+++ b/sys/kern/kern_sig.c Wed May 01 18:01:54 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sig.c,v 1.353 2019/05/01 17:21:55 kamil Exp $ */
+/* $NetBSD: kern_sig.c,v 1.354 2019/05/01 18:01:54 kamil Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.353 2019/05/01 17:21:55 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.354 2019/05/01 18:01:54 kamil Exp $");
#include "opt_ptrace.h"
#include "opt_dtrace.h"
@@ -1544,6 +1544,15 @@
KASSERT(l->l_stat == LSONPROC);
KASSERT(p->p_nrlwps > 0);
+ /*
+ * If there's a pending SIGKILL process it immediately.
+ */
+ if (p->p_xsig == SIGKILL ||
+ sigismember(&p->p_sigpend.sp_set, SIGKILL)) {
+ mutex_exit(proc_lock);
+ return;
+ }
+
p->p_xsig = signo;
p->p_sigctx.ps_faked = true;
p->p_sigctx.ps_info._signo = signo;
Home |
Main Index |
Thread Index |
Old Index