Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1716605 > unrolled thread
| Started by | Oleg Nesterov <oleg@redhat.com> |
|---|---|
| First post | 2017-08-21 17:40 +0200 |
| Last post | 2017-08-21 22:10 +0200 |
| Articles | 6 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov <oleg@redhat.com> - 2017-08-21 17:40 +0200
perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov <oleg@redhat.com> - 2017-08-21 17:40 +0200
Re: perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Peter Zijlstra <peterz@infradead.org> - 2017-08-21 21:20 +0200
Re: [PATCH] pids: make task_tgid_nr_ns() safe Linus Torvalds <torvalds@linux-foundation.org> - 2017-08-21 21:50 +0200
Re: [PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov <oleg@redhat.com> - 2017-08-22 14:30 +0200
Re: [PATCH] pids: make task_tgid_nr_ns() safe Peter Zijlstra <peterz@infradead.org> - 2017-08-21 22:10 +0200
| From | Oleg Nesterov <oleg@redhat.com> |
|---|---|
| Date | 2017-08-21 17:40 +0200 |
| Subject | [PATCH] pids: make task_tgid_nr_ns() safe |
| Message-ID | <ugWY2-67r-7@gated-at.bofh.it> |
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>
---
include/linux/pid.h | 4 +++-
include/linux/sched.h | 51 +++++++++++++++++++++++++++------------------------
kernel/pid.c | 11 ++++-------
3 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 4d17931..7195827 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -8,7 +8,9 @@ enum pid_type
PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
- PIDTYPE_MAX
+ PIDTYPE_MAX,
+ /* only valid to __task_pid_nr_ns() */
+ __PIDTYPE_TGID
};
/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8337e2d..c05ac5f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1163,13 +1163,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
return tsk->tgid;
}
-extern pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
-
-static inline pid_t task_tgid_vnr(struct task_struct *tsk)
-{
- return pid_vnr(task_tgid(tsk));
-}
-
/**
* pid_alive - check that a task structure is not stale
* @p: Task structure to be checked.
@@ -1185,23 +1178,6 @@ static inline int pid_alive(const struct task_struct *p)
return p->pids[PIDTYPE_PID].pid != NULL;
}
-static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
-{
- pid_t pid = 0;
-
- rcu_read_lock();
- if (pid_alive(tsk))
- pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
- rcu_read_unlock();
-
- return pid;
-}
-
-static inline pid_t task_ppid_nr(const struct task_struct *tsk)
-{
- return task_ppid_nr_ns(tsk, &init_pid_ns);
-}
-
static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
{
return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns);
@@ -1223,6 +1199,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL);
}
+static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
+}
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
+}
+
+static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
+{
+ pid_t pid = 0;
+
+ rcu_read_lock();
+ if (pid_alive(tsk))
+ pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
+ rcu_read_unlock();
+
+ return pid;
+}
+
+static inline pid_t task_ppid_nr(const struct task_struct *tsk)
+{
+ return task_ppid_nr_ns(tsk, &init_pid_ns);
+}
+
/* Obsolete, do not use: */
static inline pid_t task_pgrp_nr(struct task_struct *tsk)
{
diff --git a/kernel/pid.c b/kernel/pid.c
index c69c30d..020dedb 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,
if (!ns)
ns = task_active_pid_ns(current);
if (likely(pid_alive(task))) {
- if (type != PIDTYPE_PID)
+ if (type != PIDTYPE_PID) {
+ if (type == __PIDTYPE_TGID)
+ type = PIDTYPE_PID;
task = task->group_leader;
+ }
nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns);
}
rcu_read_unlock();
@@ -537,12 +540,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
}
EXPORT_SYMBOL(__task_pid_nr_ns);
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
-{
- return pid_nr_ns(task_tgid(tsk), ns);
-}
-EXPORT_SYMBOL(task_tgid_nr_ns);
-
struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
{
return ns_of_pid(task_pid(tsk));
--
2.5.0
[toc] | [next] | [standalone]
| From | Oleg Nesterov <oleg@redhat.com> |
|---|---|
| Date | 2017-08-21 17:40 +0200 |
| Subject | perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) |
| Message-ID | <ugWY3-67r-45@gated-at.bofh.it> |
| In reply to | #1716605 |
On 08/21, Oleg Nesterov wrote:
>
> 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.
Peter,
we already discussed this before, but I can't recall the result...
perf_event_pid() can hit this problem too, with this patch the problem
goes away but (with or without this patch) we do not want to report zero
pids to avoid the confusion with idle threads, right?
So do you think the patch below makes sense or we do not care?
Oleg.
---
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1249,26 +1249,31 @@ unclone_ctx(struct perf_event_context *ctx)
return parent_ctx;
}
-static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
+static u32 perf_event_xxx(struct perf_event *event, struct task_struct *p,
+ enum pid_type type)
{
+ u32 ret;
/*
* only top level events have the pid namespace they were created in
*/
if (event->parent)
event = event->parent;
- return task_tgid_nr_ns(p, event->ns);
+ ret = __task_pid_nr_ns(p, type, event->ns);
+ /* avoid -1 if it is idle thread or runs in another ns */
+ if (!ret && !pid_alive(p))
+ ret = -1;
+ return ret;
}
-static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
+static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
{
- /*
- * only top level events have the pid namespace they were created in
- */
- if (event->parent)
- event = event->parent;
+ return perf_event_xxx(event, p, __PIDTYPE_TGID);
+}
- return task_pid_nr_ns(p, event->ns);
+static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
+{
+ return perf_event_xxx(event, p, PIDTYPE_PID);
}
/*
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-08-21 21:20 +0200 |
| Subject | Re: perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) |
| Message-ID | <uh0oV-8mG-1@gated-at.bofh.it> |
| In reply to | #1716610 |
On Mon, Aug 21, 2017 at 05:36:27PM +0200, Oleg Nesterov wrote: > On 08/21, Oleg Nesterov wrote: > > > > 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. > > Peter, > > we already discussed this before, but I can't recall the result... > > perf_event_pid() can hit this problem too, with this patch the problem > goes away but (with or without this patch) we do not want to report zero > pids to avoid the confusion with idle threads, right? > > So do you think the patch below makes sense or we do not care? Yeah, works for me. While rare I think it makes sense to distinguish between a recently dead and the idle tasks.
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-08-21 21:50 +0200 |
| Message-ID | <uh0RZ-6N-31@gated-at.bofh.it> |
| In reply to | #1716605 |
On Mon, Aug 21, 2017 at 8:35 AM, Oleg Nesterov <oleg@redhat.com> wrote:
>
> 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.
Applied.
Should it perhaps have had a "Cc: stable" on it? I didn't do so, but
it might be worth pointing Greg at this explicitly (dd1c1f2f2028
"pids: make task_tgid_nr_ns() safe").
I haven't pushed it out yet, it's going through my usual build first,
but it's in my tree.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Oleg Nesterov <oleg@redhat.com> |
|---|---|
| Date | 2017-08-22 14:30 +0200 |
| Message-ID | <uhgtI-2jA-15@gated-at.bofh.it> |
| In reply to | #1716820 |
On 08/21, Linus Torvalds wrote: > > On Mon, Aug 21, 2017 at 8:35 AM, Oleg Nesterov <oleg@redhat.com> wrote: > > > > 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. > > Applied. > > Should it perhaps have had a "Cc: stable" on it? I didn't do so, but > it might be worth pointing Greg at this explicitly (dd1c1f2f2028 > "pids: make task_tgid_nr_ns() safe"). Yes, agreed, I forgot to add this tag. Oleg.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-08-21 22:10 +0200 |
| Message-ID | <uh1bk-tH-17@gated-at.bofh.it> |
| In reply to | #1716605 |
On Mon, Aug 21, 2017 at 05:35:02PM +0200, Oleg Nesterov wrote: > 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> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web