[kernel/f19] Fix cgroup destroy oops (rhbz 1045755)

Josh Boyer jwboyer at fedoraproject.org
Wed Feb 12 15:41:43 UTC 2014


commit 54301896e71b9ba4575e7a228ea392cb31054c9f
Author: Josh Boyer <jwboyer at fedoraproject.org>
Date:   Wed Feb 12 10:37:45 2014 -0500

    Fix cgroup destroy oops (rhbz 1045755)

 cgroup-fixes.patch |  178 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel.spec        |    7 ++
 2 files changed, 185 insertions(+), 0 deletions(-)
---
diff --git a/cgroup-fixes.patch b/cgroup-fixes.patch
new file mode 100644
index 0000000..0f6f1a5
--- /dev/null
+++ b/cgroup-fixes.patch
@@ -0,0 +1,178 @@
+Bugzilla: 1045775
+Upstream-status: queued for 3.14-rc3 and stable 3.12+
+
+Path: news.gmane.org!not-for-mail
+From: Michal Hocko <mhocko at suse.cz>
+Newsgroups: gmane.linux.kernel,gmane.linux.kernel.cgroups
+Subject: Re: [PATCH] cgroup: protect modifications to cgroup_idr with
+ cgroup_mutex
+Date: Wed, 12 Feb 2014 10:12:38 +0100
+Lines: 127
+Approved: news at gmane.org
+Message-ID: <20140212091238.GC28085 at dhcp22.suse.cz>
+References: <52F9D9DA.7040108 at huawei.com>
+ <20140211102032.GA11946 at dhcp22.suse.cz>
+NNTP-Posting-Host: plane.gmane.org
+Mime-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+X-Trace: ger.gmane.org 1392196376 529 80.91.229.3 (12 Feb 2014 09:12:56 GMT)
+X-Complaints-To: usenet at ger.gmane.org
+NNTP-Posting-Date: Wed, 12 Feb 2014 09:12:56 +0000 (UTC)
+Cc: Tejun Heo <tj at kernel.org>, LKML <linux-kernel at vger.kernel.org>,
+	Cgroups <cgroups at vger.kernel.org>
+To: Li Zefan <lizefan at huawei.com>
+Original-X-From: linux-kernel-owner at vger.kernel.org Wed Feb 12 10:13:03 2014
+Return-path: <linux-kernel-owner at vger.kernel.org>
+Envelope-to: glk-linux-kernel-3 at plane.gmane.org
+Original-Received: from vger.kernel.org ([209.132.180.67])
+	by plane.gmane.org with esmtp (Exim 4.69)
+	(envelope-from <linux-kernel-owner at vger.kernel.org>)
+	id 1WDVsM-0003po-4o
+	for glk-linux-kernel-3 at plane.gmane.org; Wed, 12 Feb 2014 10:13:02 +0100
+Original-Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
+	id S1751758AbaBLJMs (ORCPT <rfc822;glk-linux-kernel-3 at m.gmane.org>);
+	Wed, 12 Feb 2014 04:12:48 -0500
+Original-Received: from cantor2.suse.de ([195.135.220.15]:34766 "EHLO mx2.suse.de"
+	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
+	id S1750890AbaBLJMk (ORCPT <rfc822;linux-kernel at vger.kernel.org>);
+	Wed, 12 Feb 2014 04:12:40 -0500
+Original-Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254])
+	by mx2.suse.de (Postfix) with ESMTP id 216F1ABB2;
+	Wed, 12 Feb 2014 09:12:39 +0000 (UTC)
+Content-Disposition: inline
+In-Reply-To: <20140211102032.GA11946 at dhcp22.suse.cz>
+User-Agent: Mutt/1.5.21 (2010-09-15)
+Original-Sender: linux-kernel-owner at vger.kernel.org
+Precedence: bulk
+List-ID: <linux-kernel.vger.kernel.org>
+X-Mailing-List: linux-kernel at vger.kernel.org
+Xref: news.gmane.org gmane.linux.kernel:1646465 gmane.linux.kernel.cgroups:10357
+Archived-At: <http://permalink.gmane.org/gmane.linux.kernel/1646465>
+
+Li has pointed out that my previous backport was not correct because
+err_unlock label releases a reference to supperblock which was not taken
+before idr_alloc. I've also removed cgroup_mutex from free_css_id as per
+Li.
+Fixed in this version.
+
+--- 
+Date: Tue, 11 Feb 2014 16:05:46 +0800
+From: Li Zefan <lizefan at huawei.com>
+Subject: [PATCH - for 3.12] cgroup: protect modifications to cgroup_idr with cgroup_mutex
+
+Setup cgroupfs like this:
+  # mount -t cgroup -o cpuacct xxx /cgroup
+  # mkdir /cgroup/sub1
+  # mkdir /cgroup/sub2
+
+Then run these two commands:
+  # for ((; ;)) { mkdir /cgroup/sub1/tmp && rmdir /mnt/sub1/tmp; } &
+  # for ((; ;)) { mkdir /cgroup/sub2/tmp && rmdir /mnt/sub2/tmp; } &
+
+After seconds you may see this warning:
+
+------------[ cut here ]------------
+WARNING: CPU: 1 PID: 25243 at lib/idr.c:527 sub_remove+0x87/0x1b0()
+idr_remove called for id=6 which is not allocated.
+...
+Call Trace:
+ [<ffffffff8156063c>] dump_stack+0x7a/0x96
+ [<ffffffff810591ac>] warn_slowpath_common+0x8c/0xc0
+ [<ffffffff81059296>] warn_slowpath_fmt+0x46/0x50
+ [<ffffffff81300aa7>] sub_remove+0x87/0x1b0
+ [<ffffffff810f3f02>] ? css_killed_work_fn+0x32/0x1b0
+ [<ffffffff81300bf5>] idr_remove+0x25/0xd0
+ [<ffffffff810f2bab>] cgroup_destroy_css_killed+0x5b/0xc0
+ [<ffffffff810f4000>] css_killed_work_fn+0x130/0x1b0
+ [<ffffffff8107cdbc>] process_one_work+0x26c/0x550
+ [<ffffffff8107eefe>] worker_thread+0x12e/0x3b0
+ [<ffffffff81085f96>] kthread+0xe6/0xf0
+ [<ffffffff81570bac>] ret_from_fork+0x7c/0xb0
+---[ end trace 2d1577ec10cf80d0 ]---
+
+It's because allocating/removing cgroup ID is not properly synchronized.
+
+The bug was introduced when we converted cgroup_ida to cgroup_idr.
+While synchronization is already done inside ida_simple_{get,remove}(),
+users are responsible for concurrent calls to idr_{alloc,remove}().
+
+[mhocko at suse.cz: ported to 3.12]
+Fixes: 4e96ee8e981b ("cgroup: convert cgroup_ida to cgroup_idr")
+Cc: <stable at vger.kernel.org> #3.12+
+Reported-by: Michal Hocko <mhocko at suse.cz>
+Signed-off-by: Li Zefan <lizefan at huawei.com>
+Signed-off-by: Michal Hocko <mhocko at suse.cz>
+---
+ include/linux/cgroup.h |    2 ++
+ kernel/cgroup.c        |   23 ++++++++++++-----------
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+--- a/include/linux/cgroup.h
++++ b/include/linux/cgroup.h
+@@ -169,6 +169,8 @@ struct cgroup {
+ 	 *
+ 	 * The ID of the root cgroup is always 0, and a new cgroup
+ 	 * will be assigned with a smallest available ID.
++	 *
++	 * Allocating/Removing ID must be protected by cgroup_mutex.
+ 	 */
+ 	int id;
+ 
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -4410,14 +4410,6 @@ static long cgroup_create(struct cgroup
+ 	rcu_assign_pointer(cgrp->name, name);
+ 
+ 	/*
+-	 * Temporarily set the pointer to NULL, so idr_find() won't return
+-	 * a half-baked cgroup.
+-	 */
+-	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
+-	if (cgrp->id < 0)
+-		goto err_free_name;
+-
+-	/*
+ 	 * Only live parents can have children.  Note that the liveliness
+ 	 * check isn't strictly necessary because cgroup_mkdir() and
+ 	 * cgroup_rmdir() are fully synchronized by i_mutex; however, do it
+@@ -4426,7 +4418,7 @@ static long cgroup_create(struct cgroup
+ 	 */
+ 	if (!cgroup_lock_live_group(parent)) {
+ 		err = -ENODEV;
+-		goto err_free_id;
++		goto err_free_name;
+ 	}
+ 
+ 	/* Grab a reference on the superblock so the hierarchy doesn't
+@@ -4436,6 +4428,14 @@ static long cgroup_create(struct cgroup
+ 	 * fs */
+ 	atomic_inc(&sb->s_active);
+ 
++	/*
++	 * Temporarily set the pointer to NULL, so idr_find() won't return
++	 * a half-baked cgroup.
++	 */
++	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
++	if (cgrp->id < 0)
++		goto err_unlock;
++
+ 	init_cgroup_housekeeping(cgrp);
+ 
+ 	dentry->d_fsdata = cgrp;
+@@ -4542,11 +4542,11 @@ err_free_all:
+ 			ss->css_free(css);
+ 		}
+ 	}
++	idr_remove(&root->cgroup_idr, cgrp->id);
++err_unlock:
+ 	mutex_unlock(&cgroup_mutex);
+ 	/* Release the reference count that we took on the superblock */
+ 	deactivate_super(sb);
+-err_free_id:
+-	idr_remove(&root->cgroup_idr, cgrp->id);
+ err_free_name:
+ 	kfree(rcu_dereference_raw(cgrp->name));
+ err_free_cgrp:
+-- 
+Michal Hocko
+SUSE Labs
diff --git a/kernel.spec b/kernel.spec
index 7baf54c..0be2654 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -776,6 +776,9 @@ Patch25188: SELinux-Fix-kernel-BUG-on-empty-security-contexts.patch
 #rhbz 1031296
 Patch25189: tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch
 
+#rhbz 1045755
+Patch25195: cgroup-fixes.patch
+
 # END OF PATCH DEFINITIONS
 
 %endif
@@ -1491,6 +1494,9 @@ ApplyPatch SELinux-Fix-kernel-BUG-on-empty-security-contexts.patch
 #rhbz 1031296
 ApplyPatch tick-Clear-broadcast-pending-bit-when-switching-to-oneshot.patch
 
+#rhbz 1045755
+ApplyPatch cgroup-fixes.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2304,6 +2310,7 @@ fi
 
 %changelog
 * Wed Feb 12 2014 Josh Boyer <jwboyer at fedoraproject.org>
+- Fix cgroup destroy oops (rhbz 1045755)
 - Fix backtrace in amd_e400_idle (rhbz 1031296)
 - CVE-2014-1874 SELinux: local denial of service (rhbz 1062356 1062507)
 


More information about the scm-commits mailing list