}
}
+EXPORT_SYMBOL_GPL(flush_signal_handlers);
/* Notify the system that a driver wants to block all signals for this
* process, and wants to be notified if any signals at all were to be
struct task_struct *t)
{
int error = -EINVAL;
+ int user;
+
if (sig < 0 || sig > _NSIG)
return error;
+
+ user = (!info ||
+ (info != SEND_SIG_PRIV &&
+ info != SEND_SIG_FORCED &&
+ SI_FROMUSER(info)));
+
error = -EPERM;
- if ((!info || ((unsigned long)info != 1 &&
- (unsigned long)info != 2 && SI_FROMUSER(info)))
- && ((sig != SIGCONT) ||
- (current->signal->session != t->signal->session))
+ if (user && (sig != SIGCONT ||
+ current->signal->session != t->signal->session)
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
return error;
+
+ error = -ESRCH;
+ if (user && !vx_check(vx_task_xid(t), VX_ADMIN|VX_IDENT))
+ return error;
+
return security_task_kill(t, info, sig);
}
spin_unlock_irq(¤t->sighand->siglock);
}
+int print_fatal_signals = 0;
+
+static void print_fatal_signal(struct pt_regs *regs, int signr)
+{
+ int i;
+ unsigned char insn;
+ printk("%s/%d: potentially unexpected fatal signal %d.\n",
+ current->comm, current->pid, signr);
+
+#ifdef __i386__
+ printk("code at %08lx: ", regs->eip);
+ for (i = 0; i < 16; i++) {
+ __get_user(insn, (unsigned char *)(regs->eip + i));
+ printk("%02x ", insn);
+ }
+#endif
+ printk("\n");
+ show_regs(regs);
+}
+
+static int __init setup_print_fatal_signals(char *str)
+{
+ get_option (&str, &print_fatal_signals);
+
+ return 1;
+}
+
+__setup("print-fatal-signals=", setup_print_fatal_signals);
+
#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
static void
if (!signr)
break; /* will return 0 */
+ if ((signr == SIGSEGV) && print_fatal_signals) {
+ spin_unlock_irq(¤t->sighand->siglock);
+ print_fatal_signal(regs, signr);
+ spin_lock_irq(¤t->sighand->siglock);
+ }
+
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
ptrace_signal_deliver(regs, cookie);
* Anything else is fatal, maybe with a core dump.
*/
current->flags |= PF_SIGNALED;
+ if (print_fatal_signals)
+ print_fatal_signal(regs, signr);
if (sig_kernel_coredump(signr)) {
/*
* If it was able to dump core, this kills all
EXPORT_SYMBOL(block_all_signals);
EXPORT_SYMBOL(unblock_all_signals);
-
/*
* System call entry points.
*/