#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/security.h>
-#include <linux/syscalls.h>
#include <linux/ptrace.h>
#include <asm/param.h>
#include <asm/uaccess.h>
return sig;
}
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, int flags)
+static struct sigqueue *__sigqueue_alloc(void)
{
struct sigqueue *q = NULL;
- if (atomic_read(&t->user->sigpending) <
- t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
- q = kmem_cache_alloc(sigqueue_cachep, flags);
+ if (atomic_read(¤t->user->sigpending) <
+ current->rlim[RLIMIT_SIGPENDING].rlim_cur)
+ q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
if (q) {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
q->lock = NULL;
- q->user = get_uid(t->user);
+ q->user = get_uid(current->user);
atomic_inc(&q->user->sigpending);
}
return(q);
if (sig < 0 || sig > _NSIG)
return error;
+
user = (!info ||
(info != SEND_SIG_PRIV &&
info != SEND_SIG_FORCED &&
make sure at least one signal gets delivered and don't
pass on the info struct. */
- q = __sigqueue_alloc(t, GFP_ATOMIC);
+ if (atomic_read(&t->user->sigpending) <
+ t->rlim[RLIMIT_SIGPENDING].rlim_cur)
+ q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
+
if (q) {
+ q->flags = 0;
+ q->user = get_uid(t->user);
+ atomic_inc(&q->user->sigpending);
list_add_tail(&q->list, &signals->list);
switch ((unsigned long) info) {
case 0:
int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
{
- struct task_struct *p = NULL;
+ struct task_struct *p;
int retval, success;
if (pgrp <= 0)
return error;
}
+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);
/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
{
struct sigqueue *q;
- if ((q = __sigqueue_alloc(current, GFP_KERNEL)))
+ if ((q = __sigqueue_alloc()))
q->flags |= SIGQUEUE_PREALLOC;
return(q);
}
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
print_fatal_signal(regs, signr);
spin_lock_irq(¤t->sighand->siglock);
}
-
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
ptrace_signal_deliver(regs, cookie);
current->flags |= PF_SIGNALED;
if (print_fatal_signals)
print_fatal_signal(regs, signr);
- if (sig_kernel_coredump(signr)) {
+ if (sig_kernel_coredump(signr) &&
+ do_coredump((long)signr, signr, regs)) {
/*
- * If it was able to dump core, this kills all
- * other threads in the group and synchronizes with
- * their demise. If we lost the race with another
- * thread getting here, it set group_exit_code
- * first and our do_group_exit call below will use
- * that value and ignore the one we pass it.
+ * That killed all other threads in the group and
+ * synchronized with their demise, so there can't
+ * be any more left to kill now. The group_exit
+ * flags are set by do_coredump. Note that
+ * thread_group_empty won't always be true yet,
+ * because those threads were blocked in __exit_mm
+ * and we just let them go to finish dying.
*/
- do_coredump((long)signr, signr, regs);
+ const int code = signr | 0x80;
+ BUG_ON(!current->signal->group_exit);
+ BUG_ON(current->signal->group_exit_code != code);
+ do_exit(code);
+ /* NOTREACHED */
}
/*