From 2c707d9bf1f45ce6cec9eb99e4a288e5aef87929 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 16 Feb 2003 19:51:37 -0800 Subject: Fix locking for "send_sig_info()", to avoid possible races with signal state changes due to execve() and exit(). We need to hold the tasklist lock to guarantee stability of "task->sighand". --- kernel/signal.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/signal.c b/kernel/signal.c index b8fc6a05c031..b7ac6a557ddb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1109,21 +1109,31 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) * These are for backward compatibility with the rest of the kernel source. */ +/* + * XXX should probably nix these interfaces and update the kernel + * to specify explicitly whether the signal is a group signal or + * specific to a thread. + */ int send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { int ret; - /* XXX should nix these interfaces and update the kernel */ + /* + * We need the tasklist lock even for the specific + * thread case (when we don't need to follow the group + * lists) in order to avoid races with "p->sighand" + * going away or changing from under us. + */ + read_lock(&tasklist_lock); if (T(sig, SIG_KERNEL_BROADCAST_MASK)) { - read_lock(&tasklist_lock); ret = group_send_sig_info(sig, info, p); - read_unlock(&tasklist_lock); } else { spin_lock_irq(&p->sighand->siglock); ret = specific_send_sig_info(sig, info, p); spin_unlock_irq(&p->sighand->siglock); } + read_unlock(&tasklist_lock); return ret; } -- cgit v1.2.3