Commit 2c707d9b authored by Linus Torvalds's avatar Linus Torvalds

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".
parent 00742b03
...@@ -1109,21 +1109,31 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) ...@@ -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. * 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 int
send_sig_info(int sig, struct siginfo *info, struct task_struct *p) send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
{ {
int ret; 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)) { if (T(sig, SIG_KERNEL_BROADCAST_MASK)) {
read_lock(&tasklist_lock);
ret = group_send_sig_info(sig, info, p); ret = group_send_sig_info(sig, info, p);
read_unlock(&tasklist_lock);
} else { } else {
spin_lock_irq(&p->sighand->siglock); spin_lock_irq(&p->sighand->siglock);
ret = specific_send_sig_info(sig, info, p); ret = specific_send_sig_info(sig, info, p);
spin_unlock_irq(&p->sighand->siglock); spin_unlock_irq(&p->sighand->siglock);
} }
read_unlock(&tasklist_lock);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment