netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: ipv4: current group_info should be put after using.
@ 2014-04-11 16:10 Wang, Xiaoming
  2014-04-11  3:11 ` David Miller
  0 siblings, 1 reply; 11+ messages in thread
From: Wang, Xiaoming @ 2014-04-11 16:10 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel
  Cc: chuansheng.liu, dongxing.zhang, xiaoming.wang

There is a memory leak in ping when call ping in dumpstate.
Current group_info had been got in ping_init_sock and group_info->usage
increased. But the usage hasn't decreased.
This will make group_info never freed and cause memory leak.

unreferenced object 0xcd0e8840 (size 192):
  comm "dumpstate", pid 7583, jiffies 78360 (age 91.810s)
  hex dump (first 32 bytes):
    02 00 00 00 06 00 00 00 01 00 00 00 ef 03 00 00  ................
    f1 03 00 00 f7 03 00 00 04 04 00 00 bb 0b 00 00  ................
  backtrace:
    [<c1a6bbfc>] kmemleak_alloc+0x3c/0xa0
    [<c1320457>] __kmalloc+0xe7/0x1d0
    [<c1267c04>] groups_alloc+0x34/0xb0
    [<c1267e5c>] SyS_setgroups+0x3c/0xf0
    [<c1a864a8>] syscall_call+0x7/0xb
    [<ffffffff>] 0xffffffff

Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
---
 net/ipv4/ping.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..2af7b1f 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -255,23 +255,28 @@ int ping_init_sock(struct sock *sk)
 	struct group_info *group_info = get_current_groups();
 	int i, j, count = group_info->ngroups;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
-		return 0;
+		goto EXIT;
 
 	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++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				return 0;
+				goto EXIT;
 		}
 
 		count -= cp_count;
 	}
 
-	return -EACCES;
+	ret = -EACCES;
+
+EXIT:
+	put_group_info(group_info);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ping_init_sock);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] net: ipv4: current group_info should be put after using.
@ 2014-04-11 17:37 Wang, Xiaoming
  2014-04-11  8:35 ` Mateusz Guzik
  0 siblings, 1 reply; 11+ messages in thread
From: Wang, Xiaoming @ 2014-04-11 17:37 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel
  Cc: chuansheng.liu, dongxing.zhang, xiaoming.wang

There is a memory leak in ping. Current group_info had been got in 
ping_init_sock and group_info->usage increased. 
But the usage hasn't decreased anywhere in ping.
This will make this group_info never freed and cause memory leak.

unreferenced object 0xcd0e8840 (size 192):
  comm "dumpstate", pid 7583, jiffies 78360 (age 91.810s)
  hex dump (first 32 bytes):
    02 00 00 00 06 00 00 00 01 00 00 00 ef 03 00 00  ................
    f1 03 00 00 f7 03 00 00 04 04 00 00 bb 0b 00 00  ................
  backtrace:
    [<c1a6bbfc>] kmemleak_alloc+0x3c/0xa0
    [<c1320457>] __kmalloc+0xe7/0x1d0
    [<c1267c04>] groups_alloc+0x34/0xb0
    [<c1267e5c>] SyS_setgroups+0x3c/0xf0
    [<c1a864a8>] syscall_call+0x7/0xb
    [<ffffffff>] 0xffffffff

Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
---
 net/ipv4/ping.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..2af7b1f 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -255,23 +255,28 @@ int ping_init_sock(struct sock *sk)
 	struct group_info *group_info = get_current_groups();
 	int i, j, count = group_info->ngroups;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
-		return 0;
+		goto out_release_group;
 
 	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++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				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);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] net: ipv4: current group_info should be put after using.
@ 2014-04-12  2:53 Wang, Xiaoming
  2014-04-11 13:50 ` Mateusz Guzik
  0 siblings, 1 reply; 11+ messages in thread
From: Wang, Xiaoming @ 2014-04-12  2:53 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel
  Cc: chuansheng.liu, dongxing.zhang, xiaoming.wang

This is a typical refcount leak exploitable by unprivileged users.
Current group_info had been got in ping_init_sock and
group_info->usage increased. But the usage hasn't decreased
anywhere in ping. This will make this group_info never freed.

Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
---
 net/ipv4/ping.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..8210964 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk)
 {
 	struct net *net = sock_net(sk);
 	kgid_t group = current_egid();
-	struct group_info *group_info = get_current_groups();
-	int i, j, count = group_info->ngroups;
+	struct group_info *group_info;
+	int i, j, count;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
 		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++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				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);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] net: ipv4: current group_info should be put after using.
@ 2014-04-14 16:30 Wang, Xiaoming
  2014-04-14  2:54 ` David Miller
  0 siblings, 1 reply; 11+ messages in thread
From: Wang, Xiaoming @ 2014-04-14 16:30 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel,
	mguzik
  Cc: chuansheng.liu, dongxing.zhang, xiaoming.wang

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@intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
---
 net/ipv4/ping.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..8210964 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk)
 {
 	struct net *net = sock_net(sk);
 	kgid_t group = current_egid();
-	struct group_info *group_info = get_current_groups();
-	int i, j, count = group_info->ngroups;
+	struct group_info *group_info;
+	int i, j, count;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
 		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++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				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);
 
-- 
1.7.1

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

end of thread, other threads:[~2014-05-11 21:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-11 16:10 [PATCH] net: ipv4: current group_info should be put after using Wang, Xiaoming
2014-04-11  3:11 ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2014-04-11 17:37 Wang, Xiaoming
2014-04-11  8:35 ` Mateusz Guzik
2014-04-11 13:33   ` Mateusz Guzik
2014-04-12  2:53 Wang, Xiaoming
2014-04-11 13:50 ` Mateusz Guzik
2014-04-12 20:57   ` David Miller
2014-04-14 16:30 Wang, Xiaoming
2014-04-14  2:54 ` David Miller
2014-05-11 21:55   ` Mateusz Guzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).