diff options
| author | Oleg Nesterov <oleg@redhat.com> | 2017-08-21 11:35:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-08-21 15:47:31 -0400 |
| commit | dd1c1f2f2028a7b851f701fc6a8ebe39dcb95e7c (patch) | |
| tree | 96b5e5466504cc8c88b0f0435e80f70f0c627c58 /kernel | |
| parent | 14ccee78fc82f5512908f4424f541549a5705b89 (diff) | |
pids: make task_tgid_nr_ns() safe
This was reported many times, and this was even mentioned in commit
52ee2dfdd4f5 ("pids: refactor vnr/nr_ns helpers to make them safe") but
somehow nobody bothered to fix the obvious problem: task_tgid_nr_ns() is
not safe because task->group_leader points to nowhere after the exiting
task passes exit_notify(), rcu_read_lock() can not help.
We really need to change __unhash_process() to nullify group_leader,
parent, and real_parent, but this needs some cleanups. Until then we
can turn task_tgid_nr_ns() into another user of __task_pid_nr_ns() and
fix the problem.
Reported-by: Troy Kensinger <tkensinger@google.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/pid.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/kernel/pid.c b/kernel/pid.c index c69c30d827e5..020dedbdf066 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
| @@ -527,8 +527,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, | |||
| 527 | if (!ns) | 527 | if (!ns) |
| 528 | ns = task_active_pid_ns(current); | 528 | ns = task_active_pid_ns(current); |
| 529 | if (likely(pid_alive(task))) { | 529 | if (likely(pid_alive(task))) { |
| 530 | if (type != PIDTYPE_PID) | 530 | if (type != PIDTYPE_PID) { |
| 531 | if (type == __PIDTYPE_TGID) | ||
| 532 | type = PIDTYPE_PID; | ||
| 531 | task = task->group_leader; | 533 | task = task->group_leader; |
| 534 | } | ||
| 532 | nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); | 535 | nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); |
| 533 | } | 536 | } |
| 534 | rcu_read_unlock(); | 537 | rcu_read_unlock(); |
| @@ -537,12 +540,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, | |||
| 537 | } | 540 | } |
| 538 | EXPORT_SYMBOL(__task_pid_nr_ns); | 541 | EXPORT_SYMBOL(__task_pid_nr_ns); |
| 539 | 542 | ||
| 540 | pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) | ||
| 541 | { | ||
| 542 | return pid_nr_ns(task_tgid(tsk), ns); | ||
| 543 | } | ||
| 544 | EXPORT_SYMBOL(task_tgid_nr_ns); | ||
| 545 | |||
| 546 | struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) | 543 | struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) |
| 547 | { | 544 | { |
| 548 | return ns_of_pid(task_pid(tsk)); | 545 | return ns_of_pid(task_pid(tsk)); |
