diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2014-09-15 19:43:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-16 15:19:23 -0400 |
commit | 44b75e43178276f57141c314661526496e85a3ab (patch) | |
tree | aece79e280b9b15696e876b3772b460aa968674e | |
parent | c1f570a6abc192f047550743f9957b617af605af (diff) |
net_sched: fix memory leak in cls_tcindex
Fixes: commit 331b72922c5f58d48fd ("net: sched: RCU cls_tcindex")
Cc: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-By: John Fastabend <john.r.fastabend@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/cls_tcindex.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index dd2d691f0bbb..ee525426b3d4 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c | |||
@@ -242,8 +242,10 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
242 | * perfect hash and hash pointers from old data. | 242 | * perfect hash and hash pointers from old data. |
243 | */ | 243 | */ |
244 | cp = kzalloc(sizeof(*cp), GFP_KERNEL); | 244 | cp = kzalloc(sizeof(*cp), GFP_KERNEL); |
245 | if (!cp) | 245 | if (!cp) { |
246 | return -ENOMEM; | 246 | err = -ENOMEM; |
247 | goto errout; | ||
248 | } | ||
247 | 249 | ||
248 | cp->mask = p->mask; | 250 | cp->mask = p->mask; |
249 | cp->shift = p->shift; | 251 | cp->shift = p->shift; |
@@ -257,6 +259,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
257 | sizeof(*r) * cp->hash, GFP_KERNEL); | 259 | sizeof(*r) * cp->hash, GFP_KERNEL); |
258 | if (!cp->perfect) | 260 | if (!cp->perfect) |
259 | goto errout; | 261 | goto errout; |
262 | balloc = 1; | ||
260 | } | 263 | } |
261 | cp->h = p->h; | 264 | cp->h = p->h; |
262 | 265 | ||
@@ -282,9 +285,9 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
282 | if (cp->perfect) { | 285 | if (cp->perfect) { |
283 | if (!valid_perfect_hash(cp) || | 286 | if (!valid_perfect_hash(cp) || |
284 | cp->hash > cp->alloc_hash) | 287 | cp->hash > cp->alloc_hash) |
285 | goto errout; | 288 | goto errout_alloc; |
286 | } else if (cp->h && cp->hash != cp->alloc_hash) { | 289 | } else if (cp->h && cp->hash != cp->alloc_hash) { |
287 | goto errout; | 290 | goto errout_alloc; |
288 | } | 291 | } |
289 | 292 | ||
290 | err = -EINVAL; | 293 | err = -EINVAL; |
@@ -311,7 +314,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
311 | */ | 314 | */ |
312 | if (cp->perfect || valid_perfect_hash(cp)) | 315 | if (cp->perfect || valid_perfect_hash(cp)) |
313 | if (handle >= cp->alloc_hash) | 316 | if (handle >= cp->alloc_hash) |
314 | goto errout; | 317 | goto errout_alloc; |
315 | 318 | ||
316 | 319 | ||
317 | err = -ENOMEM; | 320 | err = -ENOMEM; |
@@ -321,7 +324,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
321 | 324 | ||
322 | cp->perfect = kcalloc(cp->hash, sizeof(*r), GFP_KERNEL); | 325 | cp->perfect = kcalloc(cp->hash, sizeof(*r), GFP_KERNEL); |
323 | if (!cp->perfect) | 326 | if (!cp->perfect) |
324 | goto errout; | 327 | goto errout_alloc; |
325 | for (i = 0; i < cp->hash; i++) | 328 | for (i = 0; i < cp->hash; i++) |
326 | tcf_exts_init(&cp->perfect[i].exts, | 329 | tcf_exts_init(&cp->perfect[i].exts, |
327 | TCA_TCINDEX_ACT, | 330 | TCA_TCINDEX_ACT, |
@@ -335,7 +338,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, | |||
335 | GFP_KERNEL); | 338 | GFP_KERNEL); |
336 | 339 | ||
337 | if (!hash) | 340 | if (!hash) |
338 | goto errout; | 341 | goto errout_alloc; |
339 | 342 | ||
340 | cp->h = hash; | 343 | cp->h = hash; |
341 | balloc = 2; | 344 | balloc = 2; |