All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexey Dobriyan <adobriyan@gmail.com>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Dave Jones <davej@codemonkey.org.uk>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Linux Kernel <linux-kernel@vger.kernel.org>,
	syzkaller-bugs@googlegroups.com,
	Gargi Sharma <gs051095@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>, Rik van Riel <riel@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: [TEST PATCH] pid: fix allocating pid 2 for init (was Re: proc_flush_task oops)
Date: Fri, 22 Dec 2017 19:11:23 +0300	[thread overview]
Message-ID: <20171222161123.GA2632@avx2> (raw)
In-Reply-To: <87lghuesel.fsf@xmission.com>

On Fri, Dec 22, 2017 at 08:41:54AM -0600, Eric W. Biederman wrote:
> Alexey Dobriyan <adobriyan@gmail.com> writes:

> > unshare
> > fork
> >     alloc_pid in level 1 succeeds
> >     alloc_pid in level 0 fails, ->idr_next is 2
> > fork
> >     alloc pid 2
> > exit
> >
> > Reliable reproducer and fail injection patch attached
> >
> > I'd say proper fix is allocating pids in the opposite order
> > so that failure in the last layer doesn't move IDR cursor
> > in baby child pidns.
> 
> I agree with you about changing the order.  That will make
> the code simpler and in the second loop actually conforming C code,
> and fix the immediate problem.

Something like that (barely tested)

---

 include/linux/pid_namespace.h |    2 ++
 kernel/pid.c                  |   15 +++++++++++----
 kernel/pid_namespace.c        |    3 ---
 3 files changed, 13 insertions(+), 7 deletions(-)

--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -28,6 +28,8 @@ struct pid_namespace {
 	unsigned int pid_allocated;
 	struct task_struct *child_reaper;
 	struct kmem_cache *pid_cachep;
+/* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */
+#define MAX_PID_NS_LEVEL 32
 	unsigned int level;
 	struct pid_namespace *parent;
 #ifdef CONFIG_PROC_FS
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -146,6 +146,7 @@ void free_pid(struct pid *pid)
 
 struct pid *alloc_pid(struct pid_namespace *ns)
 {
+	struct pid_namespace *pid_ns[MAX_PID_NS_LEVEL + 1];
 	struct pid *pid;
 	enum pid_type type;
 	int i, nr;
@@ -157,12 +158,19 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 	if (!pid)
 		return ERR_PTR(retval);
 
-	tmp = ns;
 	pid->level = ns->level;
 
-	for (i = ns->level; i >= 0; i--) {
+	tmp = ns;
+	do {
+		pid_ns[tmp->level] = tmp;
+		tmp = tmp->parent;
+	} while (tmp->level != 0);
+
+	for (i = 0; i <= ns->level; i++) {
 		int pid_min = 1;
 
+		tmp = pid_ns[i];
+
 		idr_preload(GFP_KERNEL);
 		spin_lock_irq(&pidmap_lock);
 
@@ -189,7 +197,6 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 
 		pid->numbers[i].nr = nr;
 		pid->numbers[i].ns = tmp;
-		tmp = tmp->parent;
 	}
 
 	if (unlikely(is_child_reaper(pid))) {
@@ -223,7 +230,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 
 out_free:
 	spin_lock_irq(&pidmap_lock);
-	while (++i <= ns->level)
+	while (--i >= 0)
 		idr_remove(&ns->idr, (pid->numbers + i)->nr);
 
 	spin_unlock_irq(&pidmap_lock);
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -80,9 +80,6 @@ static void proc_cleanup_work(struct work_struct *work)
 	pid_ns_release_proc(ns);
 }
 
-/* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */
-#define MAX_PID_NS_LEVEL 32
-
 static struct ucounts *inc_pid_namespaces(struct user_namespace *ns)
 {
 	return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES);

  reply	other threads:[~2017-12-22 16:11 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-18 21:44 proc_flush_task oops Dave Jones
2017-12-18 22:15 ` Al Viro
2017-12-18 23:10   ` Dave Jones
2017-12-18 23:50     ` Linus Torvalds
2017-12-19  1:22       ` Dave Jones
2017-12-19  3:39       ` Dave Jones
2017-12-19 10:49         ` Tetsuo Handa
2017-12-19 18:25           ` Eric W. Biederman
2017-12-19 18:27         ` Eric W. Biederman
2017-12-19 19:30           ` Dave Jones
2017-12-19 21:44             ` Eric W. Biederman
2017-12-20  1:54               ` Eric W. Biederman
2017-12-20  5:28                 ` Dave Jones
2017-12-20 18:25                   ` Eric W. Biederman
2017-12-21  3:16                     ` Dave Jones
2017-12-21  8:26                       ` Eric W. Biederman
2017-12-21 10:38                         ` Alexey Dobriyan
2017-12-21 14:25                           ` Dave Jones
2017-12-21 16:41                             ` Eric W. Biederman
2017-12-21 22:00                           ` Dave Jones
2017-12-22  1:31                             ` Eric W. Biederman
2017-12-22  3:35                               ` Dave Jones
2017-12-22  7:58                                 ` Eric W. Biederman
2017-12-22 10:13                                   ` Alexey Dobriyan
2017-12-22 14:41                                     ` Eric W. Biederman
2017-12-22 16:11                                       ` Alexey Dobriyan [this message]
2017-12-24  3:12                                         ` [TEST PATCH] pid: fix allocating pid 2 for init (was Re: proc_flush_task oops) Eric W. Biederman
2017-12-24  3:16                                           ` [PATCH] pid: Handle failure to allocate the first pid in a pid namespace Eric W. Biederman
2017-12-20  8:00                 ` proc_flush_task oops Dmitry Vyukov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171222161123.GA2632@avx2 \
    --to=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=davej@codemonkey.org.uk \
    --cc=ebiederm@xmission.com \
    --cc=gs051095@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=riel@redhat.com \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.