summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2013-01-15 02:03:39 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2013-01-15 02:03:39 +0000
commit30678f30c3762aa9ec49cca79174c1c3acc34942 (patch)
treecd654c98edcdded769da7807565aa22c4d6e94de /sys
parent54e04668b72a7e51fa97923d740f133acbd11e9e (diff)
Allow SIGKILL to terminate coredumping processes. Semantics decided
with kettenis guenther and beck. ok guenther
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_sig.c15
-rw-r--r--sys/sys/proc.h11
-rw-r--r--sys/uvm/uvm_unix.c5
3 files changed, 23 insertions, 8 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 0820b9c0501..a817906af65 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.146 2013/01/15 01:34:27 deraadt Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.147 2013/01/15 02:03:38 deraadt Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -803,6 +803,14 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
mask = sigmask(signum);
if (type == SPROCESS) {
+ /* Accept SIGKILL to coredumping processes */
+ if (pr->ps_flags & PS_COREDUMP && signum == SIGKILL) {
+ if (pr->ps_single != NULL)
+ p = pr->ps_single;
+ atomic_setbits_int(&p->p_siglist, mask);
+ return;
+ }
+
/*
* A process-wide signal can be diverted to a different
* thread that's in sigwait() for this signal. If there
@@ -1414,6 +1422,8 @@ coredump(struct proc *p)
char name[sizeof("/var/crash/") + MAXCOMLEN + sizeof(".core")];
char *dir = "";
+ p->p_p->ps_flags |= PS_COREDUMP;
+
/*
* Don't dump if not root and the process has used set user or
* group privileges, unless the nosuidcoredump sysctl is set to 2,
@@ -1540,6 +1550,9 @@ coredump_write(void *cookie, enum uio_seg segflg, const void *data, size_t len)
csize = len;
do {
+ if (io->io_proc->p_siglist & sigmask(SIGKILL))
+ return (EINTR);
+
/* Rest of the loop sleeps with lock held, so... */
yield();
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index da04d28451d..4760b86c058 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.163 2012/09/11 15:44:19 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.164 2013/01/15 02:03:38 deraadt Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -245,6 +245,7 @@ struct process {
#define PS_SINGLEEXIT _P_SINGLEEXIT
#define PS_SINGLEUNWIND _P_SINGLEUNWIND
#define PS_EXITING _P_EXITING
+#define PS_COREDUMP _P_COREDUMP
struct proc {
TAILQ_ENTRY(proc) p_runq;
@@ -381,12 +382,10 @@ struct proc {
/* Should be moved to machine-dependent areas. */
#define P_OWEUPC 0x008000 /* Owe proc an addupc() at next ast. */
-#define _P_ISPWAIT 0x010000 /* Is parent of PPWAIT child. */
-/* XXX Not sure what to do with these, yet. */
-#define P_SSTEP 0x020000 /* proc needs single-step fixup ??? */
+#define _P_ISPWAIT 0x010000 /* Is parent of PPWAIT child. */
+#define _P_COREDUMP 0x020000 /* busy coredumping */
#define _P_SUGIDEXEC 0x040000 /* last execve() was set[ug]id */
-
#define P_SUSPSINGLE 0x080000 /* Need to stop for single threading. */
#define P_NOZOMBIE 0x100000 /* Pid 1 waits for me instead of dad */
#define _P_INEXEC 0x200000 /* Process is doing an exec right now */
@@ -415,7 +414,7 @@ struct proc {
#define P_BITS \
("\20\02CONTROLT\03INMEM\04SIGPAUSE\05PPWAIT\06PROFIL\07SELECT" \
"\010SINTR\011SUGID\012SYSTEM\013TIMEOUT\014TRACED\015WAITED\016WEXIT" \
- "\017EXEC\020PWEUPC\021ISPWAIT\022SSTEP\023SUGIDEXEC\024SUSPSINGLE" \
+ "\017EXEC\020PWEUPC\021ISPWAIT\022COREDUMPING\023SUGIDEXEC\024SUSPSINGLE" \
"\025NOZOMBIE\026INEXEC\027SYSTRACE\030CONTINUED" \
"\031SINGLEEXIT\032SINGLEUNWIND" \
"\033THREAD\034SUSPSIG\035SOFTDEP\036STOPPED\037CPUPEG")
diff --git a/sys/uvm/uvm_unix.c b/sys/uvm/uvm_unix.c
index a94bf92cbf0..11bd29f977b 100644
--- a/sys/uvm/uvm_unix.c
+++ b/sys/uvm/uvm_unix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_unix.c,v 1.44 2013/01/15 01:34:27 deraadt Exp $ */
+/* $OpenBSD: uvm_unix.c,v 1.45 2013/01/15 02:03:38 deraadt Exp $ */
/* $NetBSD: uvm_unix.c,v 1.18 2000/09/13 15:00:25 thorpej Exp $ */
/*
@@ -237,6 +237,9 @@ uvm_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
coffset = 0;
csize = (int)cseg.c_size;
do {
+ if (p->p_siglist & sigmask(SIGKILL))
+ return (EINTR);
+
/* Rest of the loop sleeps with lock held, so... */
yield();