diff options
author | Tejun Heo <tj@kernel.org> | 2011-11-21 12:32:26 -0800 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-11-21 12:32:26 -0800 |
commit | 37ad8aca94a1da2112a7c56151390914e80d1113 (patch) | |
tree | daf5f8956aa7fa7b8d3e15aaf67dd3d6fc6f2375 | |
parent | 5ece3eae4cdb968c269e0bc7e2c0e2b223552025 (diff) |
freezer: use lock_task_sighand() in fake_signal_wake_up()
cgroup_freezer calls freeze_task() without holding tasklist_lock and,
if the task is exiting, its ->sighand may be gone by the time
fake_signal_wake_up() is called. Use lock_task_sighand() instead of
accessing ->sighand directly.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Paul Menage <paul@paulmenage.org>
-rw-r--r-- | kernel/freezer.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/freezer.c b/kernel/freezer.c index c3496c6a91b2..389549f0a94e 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -93,9 +93,10 @@ static void fake_signal_wake_up(struct task_struct *p) { unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - signal_wake_up(p, 0); - spin_unlock_irqrestore(&p->sighand->siglock, flags); + if (lock_task_sighand(p, &flags)) { + signal_wake_up(p, 0); + unlock_task_sighand(p, &flags); + } } /** |