All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pids: make task_tgid_nr_ns() safe
       [not found]         ` <CA+55aFzA+0jzTdknmf0OUB7WSPgAa56nqckqdz=iDmbR2P9eRw@mail.gmail.com>
@ 2017-08-21 15:35           ` Oleg Nesterov
  2017-08-21 15:36             ` perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov
                               ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Oleg Nesterov @ 2017-08-21 15:35 UTC (permalink / raw)
  To: Linus Torvalds, Peter Zijlstra
  Cc: Kees Cook, Troy Kensinger, security, Paul McKenney,
	Josh Triplett, linux-kernel, Eric W. Biederman, Andrew Morton

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

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe)
  2017-08-21 15:35           ` [PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov
@ 2017-08-21 15:36             ` Oleg Nesterov
  2017-08-21 19:18               ` Peter Zijlstra
  2017-08-21 19:49             ` [PATCH] pids: make task_tgid_nr_ns() safe Linus Torvalds
  2017-08-21 20:05             ` Peter Zijlstra
  2 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2017-08-21 15:36 UTC (permalink / raw)
  To: Linus Torvalds, Peter Zijlstra
  Cc: Kees Cook, Troy Kensinger, security, Paul McKenney,
	Josh Triplett, linux-kernel, Eric W. Biederman, Andrew Morton

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);
 }
 
 /*

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe)
  2017-08-21 15:36             ` perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov
@ 2017-08-21 19:18               ` Peter Zijlstra
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Zijlstra @ 2017-08-21 19:18 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Linus Torvalds, Kees Cook, Troy Kensinger, security,
	Paul McKenney, Josh Triplett, linux-kernel, Eric W. Biederman,
	Andrew Morton

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.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] pids: make task_tgid_nr_ns() safe
  2017-08-21 15:35           ` [PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov
  2017-08-21 15:36             ` perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov
@ 2017-08-21 19:49             ` Linus Torvalds
  2017-08-22 12:20               ` Oleg Nesterov
  2017-08-21 20:05             ` Peter Zijlstra
  2 siblings, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2017-08-21 19:49 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Peter Zijlstra, Kees Cook, Troy Kensinger, security,
	Paul McKenney, Josh Triplett, Linux Kernel Mailing List,
	Eric W. Biederman, Andrew Morton

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] pids: make task_tgid_nr_ns() safe
  2017-08-21 15:35           ` [PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov
  2017-08-21 15:36             ` perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov
  2017-08-21 19:49             ` [PATCH] pids: make task_tgid_nr_ns() safe Linus Torvalds
@ 2017-08-21 20:05             ` Peter Zijlstra
  2 siblings, 0 replies; 8+ messages in thread
From: Peter Zijlstra @ 2017-08-21 20:05 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Linus Torvalds, Kees Cook, Troy Kensinger, security,
	Paul McKenney, Josh Triplett, linux-kernel, Eric W. Biederman,
	Andrew Morton

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>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] pids: make task_tgid_nr_ns() safe
  2017-08-21 19:49             ` [PATCH] pids: make task_tgid_nr_ns() safe Linus Torvalds
@ 2017-08-22 12:20               ` Oleg Nesterov
  2017-08-22 16:57                 ` Linus Torvalds
  0 siblings, 1 reply; 8+ messages in thread
From: Oleg Nesterov @ 2017-08-22 12:20 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Zijlstra, Kees Cook, Troy Kensinger, security,
	Paul McKenney, Josh Triplett, Linux Kernel Mailing List,
	Eric W. Biederman, Andrew Morton

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.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] pids: make task_tgid_nr_ns() safe
  2017-08-22 12:20               ` Oleg Nesterov
@ 2017-08-22 16:57                 ` Linus Torvalds
  2017-08-22 17:51                   ` Greg KH
  0 siblings, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2017-08-22 16:57 UTC (permalink / raw)
  To: stable; +Cc: Oleg Nesterov

I suspect Greg saw this on the security list already, but let's just
cc the stable list explicitly for

    dd1c1f2f2028  ("pids: make task_tgid_nr_ns() safe")

since the original commit didn't end up having been marked.

              Linus

On Tue, Aug 22, 2017 at 5:20 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> On 08/21, Linus Torvalds wrote:
>>
>> 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.
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] pids: make task_tgid_nr_ns() safe
  2017-08-22 16:57                 ` Linus Torvalds
@ 2017-08-22 17:51                   ` Greg KH
  0 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2017-08-22 17:51 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: stable, Oleg Nesterov

On Tue, Aug 22, 2017 at 09:57:16AM -0700, Linus Torvalds wrote:
> I suspect Greg saw this on the security list already, but let's just
> cc the stable list explicitly for
> 
>     dd1c1f2f2028  ("pids: make task_tgid_nr_ns() safe")
> 
> since the original commit didn't end up having been marked.

Thanks, I picked it up now.

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-08-22 17:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAMKL9z2A8VSmLc9gz4Vtd1N5nGwR5d9Mxi1Nc8VjTQKsURoMkA@mail.gmail.com>
     [not found] ` <CA+55aFyfaBZmDVSpx3F7cQZcck8u_vg53wL1ykRE-ccgrtg14w@mail.gmail.com>
     [not found]   ` <CAGXu5jKLDAnKoRg_v8Nc7s6AtQ6_QfaMtJorjFkbaX64MDHy2g@mail.gmail.com>
     [not found]     ` <CA+55aFy+0cQUcPjWmnD8qFL2gHVYHYTxJmHVy6L=Bz03KaP2Rw@mail.gmail.com>
     [not found]       ` <20170820142953.GA3767@redhat.com>
     [not found]         ` <CA+55aFzA+0jzTdknmf0OUB7WSPgAa56nqckqdz=iDmbR2P9eRw@mail.gmail.com>
2017-08-21 15:35           ` [PATCH] pids: make task_tgid_nr_ns() safe Oleg Nesterov
2017-08-21 15:36             ` perf_event_pid() (Was: [PATCH] pids: make task_tgid_nr_ns() safe) Oleg Nesterov
2017-08-21 19:18               ` Peter Zijlstra
2017-08-21 19:49             ` [PATCH] pids: make task_tgid_nr_ns() safe Linus Torvalds
2017-08-22 12:20               ` Oleg Nesterov
2017-08-22 16:57                 ` Linus Torvalds
2017-08-22 17:51                   ` Greg KH
2017-08-21 20:05             ` Peter Zijlstra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.