aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2005-12-09 08:29:29 +0000
committerDavid Xu <davidxu@FreeBSD.org>2005-12-09 08:29:29 +0000
commitf71a882f15f93c53ec6a941726297a8e940a1d68 (patch)
treea5d9a60b7dd61f1470a9e66a08cb65b37bac52a5 /sys/kern/kern_sig.c
parent528b9bcd6e8658bcf50e4bbbb6ed7b5a8d23b397 (diff)
downloadsrc-f71a882f15f93c53ec6a941726297a8e940a1d68.tar.gz
src-f71a882f15f93c53ec6a941726297a8e940a1d68.zip
Add a sysctl to force a process to sigexit if a trap signal is
being hold by current thread or ignored by current process, otherwise, it is very possible the thread will enter an infinite loop and lead to an administrator's nightmare.
Notes
Notes: svn path=/head/; revision=153264
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 4df123a37400..4c7f6a97b6e7 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -109,6 +109,10 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW,
&kern_logsigexit, 0,
"Log processes quitting on abnormal signals to syslog(3)");
+static int kern_forcesigexit = 1;
+SYSCTL_INT(_kern, OID_AUTO, forcesigexit, CTLFLAG_RW,
+ &kern_forcesigexit, 0, "Force trap signal to be handled");
+
SYSCTL_NODE(_kern, OID_AUTO, sigqueue, CTLFLAG_RW, 0, "POSIX real time signal");
static int max_pending_per_proc = 128;
@@ -1923,6 +1927,19 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
}
mtx_unlock(&ps->ps_mtx);
} else {
+ /*
+ * Avoid a possible infinite loop if the thread
+ * masking the signal or process is ignoring the
+ * signal.
+ */
+ if (kern_forcesigexit &&
+ (SIGISMEMBER(td->td_sigmask, sig) ||
+ ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN)) {
+ SIGDELSET(td->td_sigmask, sig);
+ SIGDELSET(ps->ps_sigcatch, sig);
+ SIGDELSET(ps->ps_sigignore, sig);
+ ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
+ }
mtx_unlock(&ps->ps_mtx);
p->p_code = code; /* XXX for core dump/debugger */
p->p_sig = sig; /* XXX to verify code */