diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2011-09-20 17:21:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-03 13:45:49 -0400 |
commit | 5bb20ed863f8573ecd1956f0ebd2c3d36e6e0585 (patch) | |
tree | 45591d04c0dd9f8134c100bdfc86f96869059718 /net/caif/cfcnfg.c | |
parent | 64af1bac9b979ae1f2f052742fda06d65f497643 (diff) |
caif: add error handling for allocation
The allocation of "phyinfo" wasn't checked, and also the allocation
wasn't freed on error paths. Sjur Brændeland pointed out as well
that "phy_driver" should be freed on the error path too.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Acked-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/caif/cfcnfg.c')
-rw-r--r-- | net/caif/cfcnfg.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index f07ab8c22224..00523ecc4ced 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -467,7 +467,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | |||
467 | { | 467 | { |
468 | struct cflayer *frml; | 468 | struct cflayer *frml; |
469 | struct cflayer *phy_driver = NULL; | 469 | struct cflayer *phy_driver = NULL; |
470 | struct cfcnfg_phyinfo *phyinfo; | 470 | struct cfcnfg_phyinfo *phyinfo = NULL; |
471 | int i; | 471 | int i; |
472 | u8 phyid; | 472 | u8 phyid; |
473 | 473 | ||
@@ -482,23 +482,25 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | |||
482 | goto got_phyid; | 482 | goto got_phyid; |
483 | } | 483 | } |
484 | pr_warn("Too many CAIF Link Layers (max 6)\n"); | 484 | pr_warn("Too many CAIF Link Layers (max 6)\n"); |
485 | goto out; | 485 | goto out_err; |
486 | 486 | ||
487 | got_phyid: | 487 | got_phyid: |
488 | phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); | 488 | phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); |
489 | if (!phyinfo) | ||
490 | goto out_err; | ||
489 | 491 | ||
490 | switch (phy_type) { | 492 | switch (phy_type) { |
491 | case CFPHYTYPE_FRAG: | 493 | case CFPHYTYPE_FRAG: |
492 | phy_driver = | 494 | phy_driver = |
493 | cfserl_create(CFPHYTYPE_FRAG, phyid, stx); | 495 | cfserl_create(CFPHYTYPE_FRAG, phyid, stx); |
494 | if (!phy_driver) | 496 | if (!phy_driver) |
495 | goto out; | 497 | goto out_err; |
496 | break; | 498 | break; |
497 | case CFPHYTYPE_CAIF: | 499 | case CFPHYTYPE_CAIF: |
498 | phy_driver = NULL; | 500 | phy_driver = NULL; |
499 | break; | 501 | break; |
500 | default: | 502 | default: |
501 | goto out; | 503 | goto out_err; |
502 | } | 504 | } |
503 | phy_layer->id = phyid; | 505 | phy_layer->id = phyid; |
504 | phyinfo->pref = pref; | 506 | phyinfo->pref = pref; |
@@ -512,10 +514,8 @@ got_phyid: | |||
512 | 514 | ||
513 | frml = cffrml_create(phyid, fcs); | 515 | frml = cffrml_create(phyid, fcs); |
514 | 516 | ||
515 | if (!frml) { | 517 | if (!frml) |
516 | kfree(phyinfo); | 518 | goto out_err; |
517 | goto out; | ||
518 | } | ||
519 | phyinfo->frm_layer = frml; | 519 | phyinfo->frm_layer = frml; |
520 | layer_set_up(frml, cnfg->mux); | 520 | layer_set_up(frml, cnfg->mux); |
521 | 521 | ||
@@ -531,7 +531,12 @@ got_phyid: | |||
531 | } | 531 | } |
532 | 532 | ||
533 | list_add_rcu(&phyinfo->node, &cnfg->phys); | 533 | list_add_rcu(&phyinfo->node, &cnfg->phys); |
534 | out: | 534 | mutex_unlock(&cnfg->lock); |
535 | return; | ||
536 | |||
537 | out_err: | ||
538 | kfree(phy_driver); | ||
539 | kfree(phyinfo); | ||
535 | mutex_unlock(&cnfg->lock); | 540 | mutex_unlock(&cnfg->lock); |
536 | } | 541 | } |
537 | EXPORT_SYMBOL(cfcnfg_add_phy_layer); | 542 | EXPORT_SYMBOL(cfcnfg_add_phy_layer); |