diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | 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 6e930c7174dd..2c00e8bf684d 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -207,17 +207,22 @@ static int ping_init_sock(struct sock *sk) | |||
207 | gid_t range[2]; | 207 | gid_t range[2]; |
208 | struct group_info *group_info = get_current_groups(); | 208 | struct group_info *group_info = get_current_groups(); |
209 | int i, j, count = group_info->ngroups; | 209 | int i, j, count = group_info->ngroups; |
210 | kgid_t low, high; | ||
210 | 211 | ||
211 | inet_get_ping_group_range_net(net, range, range+1); | 212 | inet_get_ping_group_range_net(net, range, range+1); |
213 | low = make_kgid(&init_user_ns, range[0]); | ||
214 | high = make_kgid(&init_user_ns, range[1]); | ||
215 | if (!gid_valid(low) || !gid_valid(high) || gid_lt(high, low)) | ||
216 | return -EACCES; | ||
217 | |||
212 | if (range[0] <= group && group <= range[1]) | 218 | if (range[0] <= group && group <= range[1]) |
213 | return 0; | 219 | return 0; |
214 | 220 | ||
215 | for (i = 0; i < group_info->nblocks; i++) { | 221 | for (i = 0; i < group_info->nblocks; i++) { |
216 | int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); | 222 | int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); |
217 | |||
218 | for (j = 0; j < cp_count; j++) { | 223 | for (j = 0; j < cp_count; j++) { |
219 | group = group_info->blocks[i][j]; | 224 | kgid_t gid = group_info->blocks[i][j]; |
220 | if (range[0] <= group && group <= range[1]) | 225 | if (gid_lte(low, gid) && gid_lte(gid, high)) |
221 | return 0; | 226 | return 0; |
222 | } | 227 | } |
223 | 228 | ||