[PATCH][VIVID][MAKO/MANTA/FLO] net: ipv4: current group_info should be put after using.

Tyler Hicks tyhicks at canonical.com
Fri Jan 23 19:28:41 UTC 2015


From: "Wang, Xiaoming" <xiaoming.wang at intel.com>

Plug a group_info refcount leak in ping_init.
group_info is only needed during initialization and
the code failed to release the reference on exit.
While here move grabbing the reference to a place
where it is actually needed.

Signed-off-by: Chuansheng Liu <chuansheng.liu at intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang at intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang at intel.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
(cherry picked from commit b04c46190219a4f845e46a459e3102137b7f6cac)
CVE-2014-2851
BugLink: http://bugs.launchpad.net/bugs/1312994
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>

Conflicts:
	net/ipv4/ping.c
---

This fix is important for the Touch kernels because the Android init enables
the sending of ICMP echo request by unprivileged processes, meaning that an
unprivileged process can trigger this bug on Touch.

The goldfish kernel already has this patch applied so mako, manta, and flo are
the only branches this should be applied to.

I've manually tested a kernel with this patch applied on a mako device.

Thanks!

Tyler

 net/ipv4/ping.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index a8d7ed0..cce74ad 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -248,26 +248,33 @@ int ping_init_sock(struct sock *sk)
 	struct net *net = sock_net(sk);
 	gid_t group = current_egid();
 	gid_t range[2];
-	struct group_info *group_info = get_current_groups();
-	int i, j, count = group_info->ngroups;
+	struct group_info *group_info;
+	int i, j, count;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, range, range+1);
 	if (range[0] <= group && group <= range[1])
 		return 0;
 
+	group_info = get_current_groups();
+	count = group_info->ngroups;
 	for (i = 0; i < group_info->nblocks; i++) {
 		int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
 
 		for (j = 0; j < cp_count; j++) {
 			group = group_info->blocks[i][j];
 			if (range[0] <= group && group <= range[1])
-				return 0;
+				goto out_release_group;
 		}
 
 		count -= cp_count;
 	}
 
-	return -EACCES;
+	ret = -EACCES;
+
+out_release_group:
+	put_group_info(group_info);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ping_init_sock);
 
-- 
2.1.0





More information about the kernel-team mailing list