aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2007-11-28 19:21:24 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-29 12:24:52 -0500
commitc895078355b6b6e05c60aa205892526dd3390f0a (patch)
tree922a0b9204b0cfcd5c59762f4d02e167d587ccd2 /kernel/exit.c
parentc2319540cd7330fa9066e5b9b84d357a2c8631a2 (diff)
wait_task_stopped(): don't use task_pid_nr_ns() lockless
wait_task_stopped(WNOWAIT) does task_pid_nr_ns() without tasklist/rcu lock, we can read an already freed memory. Use the cached pid_t value. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Looks-good-to: Roland McGrath <roland@redhat.com> Acked-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index cd0f1d4137a7..0a4a382ecf23 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1357,7 +1357,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
1357 int __user *stat_addr, struct rusage __user *ru) 1357 int __user *stat_addr, struct rusage __user *ru)
1358{ 1358{
1359 int retval, exit_code; 1359 int retval, exit_code;
1360 struct pid_namespace *ns; 1360 pid_t pid;
1361 1361
1362 if (!p->exit_code) 1362 if (!p->exit_code)
1363 return 0; 1363 return 0;
@@ -1376,12 +1376,11 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
1376 * keep holding onto the tasklist_lock while we call getrusage and 1376 * keep holding onto the tasklist_lock while we call getrusage and
1377 * possibly take page faults for user memory. 1377 * possibly take page faults for user memory.
1378 */ 1378 */
1379 ns = current->nsproxy->pid_ns; 1379 pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
1380 get_task_struct(p); 1380 get_task_struct(p);
1381 read_unlock(&tasklist_lock); 1381 read_unlock(&tasklist_lock);
1382 1382
1383 if (unlikely(noreap)) { 1383 if (unlikely(noreap)) {
1384 pid_t pid = task_pid_nr_ns(p, ns);
1385 uid_t uid = p->uid; 1384 uid_t uid = p->uid;
1386 int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED; 1385 int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
1387 1386
@@ -1451,11 +1450,11 @@ bail_ref:
1451 if (!retval && infop) 1450 if (!retval && infop)
1452 retval = put_user(exit_code, &infop->si_status); 1451 retval = put_user(exit_code, &infop->si_status);
1453 if (!retval && infop) 1452 if (!retval && infop)
1454 retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid); 1453 retval = put_user(pid, &infop->si_pid);
1455 if (!retval && infop) 1454 if (!retval && infop)
1456 retval = put_user(p->uid, &infop->si_uid); 1455 retval = put_user(p->uid, &infop->si_uid);
1457 if (!retval) 1456 if (!retval)
1458 retval = task_pid_nr_ns(p, ns); 1457 retval = pid;
1459 put_task_struct(p); 1458 put_task_struct(p);
1460 1459
1461 BUG_ON(!retval); 1460 BUG_ON(!retval);