diff options
author | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:26 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:26 -0500 |
commit | 37ad8aca94a1da2112a7c56151390914e80d1113 (patch) | |
tree | daf5f8956aa7fa7b8d3e15aaf67dd3d6fc6f2375 /kernel/freezer.c | |
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>
Diffstat (limited to 'kernel/freezer.c')
-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) | |||
93 | { | 93 | { |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | 95 | ||
96 | spin_lock_irqsave(&p->sighand->siglock, flags); | 96 | if (lock_task_sighand(p, &flags)) { |
97 | signal_wake_up(p, 0); | 97 | signal_wake_up(p, 0); |
98 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 98 | unlock_task_sighand(p, &flags); |
99 | } | ||
99 | } | 100 | } |
100 | 101 | ||
101 | /** | 102 | /** |