[PATCH cgroup/for-4.10] cgroup: cgroup_sk_alloc() is allowed to increase reference on a dead cgroup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jesús,

I applied the following patch to cgroup/for-4.10 and will soon push
out to Linus.  I'm pretty sure this is what you saw but can you please
verify that the warning goes away with it applied?

Thanks a lot for the report.

------ 8< ------
>From 89bb3eed858ec2ea36ceae822bbf81f1ef24e80d Mon Sep 17 00:00:00 2001
From: Tejun Heo <tj@xxxxxxxxxx>
Date: Mon, 12 Dec 2016 16:30:29 -0500
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When a listening socket associated with a cgroup creates a new
connection, it gets cloned and the reference on the cgroup is
incremented by calling cgroup_get().  Such a socket can be left behind
in an empty cgroup after processes are migrated away from it.  As an
empty cgroup may be removed, the socket may end up trying to clone new
sockets while associated with a removed cgroup.

This doesn't break anything in terms of reference counting; however,
as a precaution, cgroup_get() triggers WARN when it's called on a
removed cgroup, which cgroup_sk_alloc() can trigger spuriously.

We know this path is legit, open code cgroup_get() in
cgroup_sk_alloc() without the sanity check to avoid spuriously
triggering the warning.

Reported-by: Jesús Rodríguez Acosta <jesus.rodriguez.acosta@xxxxxxxxx>
Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
Link: http://lkml.kernel.org/r/CAH=7=un56LL12Meu0j+6+ZRcdsnUHomfDLuq=raC6ZtQEwLqTA@xxxxxxxxxxxxxx
Fixes: d979a39d7242 ("cgroup: duplicate cgroup reference when cloning sockets")
Cc: stable@xxxxxxxxxxxxxxx # v4.5+
Cc: Johannes Weiner <jweiner@xxxxxx>
---
 kernel/cgroup.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 85bc9be..7fe26595 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -6318,9 +6318,13 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd)
 	if (cgroup_sk_alloc_disabled)
 		return;
 
-	/* Socket clone path */
+	/*
+	 * Socket clone path.  We open-code cgroup_get() here to avoid the
+	 * cgroup_is_dead() sanity check as a listening socket left in a
+	 * dead cgroup can still get cloned for new connections.
+	 */
 	if (skcd->val) {
-		cgroup_get(sock_cgroup_ptr(skcd));
+		css_get(&sock_cgroup_ptr(skcd)->self);
 		return;
 	}
 
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe cgroups" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux