1 |
Subject [PATCH] net: ipv4: current group_info should be put after using. |
2 |
From "Wang, Xiaoming" <> |
3 |
Date Fri, 11 Apr 2014 13:37:08 -0400 |
4 |
|
5 |
|
6 |
There is a memory leak in ping. Current group_info had been got in |
7 |
ping_init_sock and group_info->usage increased. |
8 |
But the usage hasn't decreased anywhere in ping. |
9 |
This will make this group_info never freed and cause memory leak. |
10 |
|
11 |
unreferenced object 0xcd0e8840 (size 192): |
12 |
comm "dumpstate", pid 7583, jiffies 78360 (age 91.810s) |
13 |
hex dump (first 32 bytes): |
14 |
02 00 00 00 06 00 00 00 01 00 00 00 ef 03 00 00 ................ |
15 |
f1 03 00 00 f7 03 00 00 04 04 00 00 bb 0b 00 00 ................ |
16 |
backtrace: |
17 |
[<c1a6bbfc>] kmemleak_alloc+0x3c/0xa0 |
18 |
[<c1320457>] __kmalloc+0xe7/0x1d0 |
19 |
[<c1267c04>] groups_alloc+0x34/0xb0 |
20 |
[<c1267e5c>] SyS_setgroups+0x3c/0xf0 |
21 |
[<c1a864a8>] syscall_call+0x7/0xb |
22 |
[<ffffffff>] 0xffffffff |
23 |
Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com> |
24 |
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com> |
25 |
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com> |
26 |
--- |
27 |
net/ipv4/ping.c | 11 ++++++++--- |
28 |
1 files changed, 8 insertions(+), 3 deletions(-) |
29 |
|
30 |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c |
31 |
index f4b19e5..2af7b1f 100644 |
32 |
--- a/net/ipv4/ping.c |
33 |
+++ b/net/ipv4/ping.c |
34 |
@@ -207,23 +207,28 @@ static int ping_init_sock(struct sock *s |
35 |
struct group_info *group_info = get_current_groups(); |
36 |
int i, j, count = group_info->ngroups; |
37 |
kgid_t low, high; |
38 |
+ int ret = 0; |
39 |
|
40 |
inet_get_ping_group_range_net(net, &low, &high); |
41 |
if (gid_lte(low, group) && gid_lte(group, high)) |
42 |
- return 0; |
43 |
+ goto out_release_group; |
44 |
|
45 |
for (i = 0; i < group_info->nblocks; i++) { |
46 |
int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); |
47 |
for (j = 0; j < cp_count; j++) { |
48 |
kgid_t gid = group_info->blocks[i][j]; |
49 |
if (gid_lte(low, gid) && gid_lte(gid, high)) |
50 |
- return 0; |
51 |
+ goto out_release_group; |
52 |
} |
53 |
|
54 |
count -= cp_count; |
55 |
} |
56 |
|
57 |
- return -EACCES; |
58 |
+ ret = -EACCES; |
59 |
+ |
60 |
+out_release_group: |
61 |
+ put_group_info(group_info); |
62 |
+ return ret; |
63 |
} |
64 |
|
65 |
static void ping_close(struct sock *sk, long timeout) |