net: ipv4: current group_info should be put after using.
Subsystems (2)
PATCH 1/1 net: ipv4: current group_info should be put after using.
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--- net/ipv4/ping.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
net/ipv4/ping.c +8 -3
@@ -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);
Signature · 1 line
1.7.1
Quoted 5 lines · Xiaoming
There is a memory leak in ping. Current
group_infohad been got inping_init_sockandgroup_info->usageincreased.
But the usage hasn't decreased anywhere in ping.
This will make thisgroup_infonever freed and cause memory leak.
Memory leak is only one of possible side-effects, thus I believe commit message should be adjusted.
This is a typical refcount leak exploitable by unprivileged users, so side effects can range from nothing through memory leaks and crashes to possibly privilege escalation.
That said losing ' and cause memory leak' from your commit message would be fine in my opinion.
See also a nit below.
Quoted 9 lines
--- net/ipv4/ping.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)net/ipv4/ping.c +0
-0
net/ipv4/ping.c int ping_init_sock(struct sock *sk) · line 263
Quoted 10 lines
net/ipv4/ping.c +2
-1@@ -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;
Since group_info is not even used here maybe it would be better to leave return 0 as it is and call get_current_groups before the loop?
Quoted 21 lines
net/ipv4/ping.c +6
-2for (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);
Signature · 1 line
Mateusz Guzik
Quoted 10 lines · Mateusz Guzik
Quoted 5 lines · Xiaoming
There is a memory leak in ping. Current
group_infohad been got inping_init_sockandgroup_info->usageincreased.
But the usage hasn't decreased anywhere in ping.
This will make thisgroup_infonever freed and cause memory leak.Memory leak is only one of possible side-effects, thus I believe commit message should be adjusted.
Quoted 7 lines
This is a typical refcount leak exploitable by unprivileged users, so side effects can range from nothing through memory leaks and crashes to possibly privilege escalation.
That said losing ' and cause memory leak' from your commit message would be fine in my opinion.
Huh, not sure why I wrote that last sentence, it does not make much sense. Sorry.
There is a pending CVE request for this bug:
http://seclists.org/oss-sec/2014/q2/97
The bug was introduced with:
commit c319b4d76b9e583a5d88d6bf190e079c4e43213d
Author: Vasiliy Kulikov <[email protected]> Date: Fri May 13 10:01:00 2011 +0000
net: ipv4: add IPPROTO_ICMP socket kind
starting with 3.0 kernel.
Quoted 49 lines
See also a nit below.
Quoted 9 lines
--- net/ipv4/ping.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)net/ipv4/ping.c +0
-0net/ipv4/ping.c int ping_init_sock(struct sock *sk) · line 263
Quoted 10 lines
net/ipv4/ping.c +2
-1@@ -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;Since
group_infois not even used here maybe it would be better to leave return 0 as it is and callget_current_groupsbefore the loop?Quoted 21 lines
net/ipv4/ping.c +6
-2for (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);Signature · 1 line
Mateusz Guzik
Signature · 1 line
Mateusz Guzik