diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2013-01-15 02:03:39 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2013-01-15 02:03:39 +0000 |
commit | 30678f30c3762aa9ec49cca79174c1c3acc34942 (patch) | |
tree | cd654c98edcdded769da7807565aa22c4d6e94de /sys | |
parent | 54e04668b72a7e51fa97923d740f133acbd11e9e (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.c | 15 | ||||
-rw-r--r-- | sys/sys/proc.h | 11 | ||||
-rw-r--r-- | sys/uvm/uvm_unix.c | 5 |
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(); |