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/pid.c | |
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/pid.c')
-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)); |