diff options
author | Vasily Averin <vvs@sw.ru> | 2006-09-27 15:54:14 -0400 |
---|---|---|
committer | Auke Kok <juke-jan.h.kok@intel.com> | 2006-09-27 15:54:14 -0400 |
commit | 793fab727324adc90a0a2889f2b1d88bae4790eb (patch) | |
tree | eadf2858ba29efe65cb416d74cb3afcc194715f3 | |
parent | dbf38c9474306297866d9c2af02c2d37c5165325 (diff) |
e1000: possible memory leak in e1000_set_ringparam
Memory allocated for new tx_ring and rx_ring leaks if
e1000_setup_XX_resources() fails.c Also this patch reduces stack usage
(removed tx_new and rx_new) and uses kzalloc instead kmalloc+memset(0)
Signed-off-by: Vasily Averin <vvs@sw.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 2cc949a34451..778ede3c0216 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -646,8 +646,8 @@ e1000_set_ringparam(struct net_device *netdev, | |||
646 | { | 646 | { |
647 | struct e1000_adapter *adapter = netdev_priv(netdev); | 647 | struct e1000_adapter *adapter = netdev_priv(netdev); |
648 | e1000_mac_type mac_type = adapter->hw.mac_type; | 648 | e1000_mac_type mac_type = adapter->hw.mac_type; |
649 | struct e1000_tx_ring *txdr, *tx_old, *tx_new; | 649 | struct e1000_tx_ring *txdr, *tx_old; |
650 | struct e1000_rx_ring *rxdr, *rx_old, *rx_new; | 650 | struct e1000_rx_ring *rxdr, *rx_old; |
651 | int i, err, tx_ring_size, rx_ring_size; | 651 | int i, err, tx_ring_size, rx_ring_size; |
652 | 652 | ||
653 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 653 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
@@ -665,23 +665,17 @@ e1000_set_ringparam(struct net_device *netdev, | |||
665 | tx_old = adapter->tx_ring; | 665 | tx_old = adapter->tx_ring; |
666 | rx_old = adapter->rx_ring; | 666 | rx_old = adapter->rx_ring; |
667 | 667 | ||
668 | adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL); | 668 | err = -ENOMEM; |
669 | if (!adapter->tx_ring) { | 669 | txdr = kzalloc(tx_ring_size, GFP_KERNEL); |
670 | err = -ENOMEM; | 670 | if (!txdr) |
671 | goto err_setup_rx; | 671 | goto err_alloc_tx; |
672 | } | ||
673 | memset(adapter->tx_ring, 0, tx_ring_size); | ||
674 | 672 | ||
675 | adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL); | 673 | rxdr = kzalloc(rx_ring_size, GFP_KERNEL); |
676 | if (!adapter->rx_ring) { | 674 | if (!rxdr) |
677 | kfree(adapter->tx_ring); | 675 | goto err_alloc_rx; |
678 | err = -ENOMEM; | ||
679 | goto err_setup_rx; | ||
680 | } | ||
681 | memset(adapter->rx_ring, 0, rx_ring_size); | ||
682 | 676 | ||
683 | txdr = adapter->tx_ring; | 677 | adapter->tx_ring = txdr; |
684 | rxdr = adapter->rx_ring; | 678 | adapter->rx_ring = rxdr; |
685 | 679 | ||
686 | rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); | 680 | rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); |
687 | rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? | 681 | rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? |
@@ -708,16 +702,14 @@ e1000_set_ringparam(struct net_device *netdev, | |||
708 | /* save the new, restore the old in order to free it, | 702 | /* save the new, restore the old in order to free it, |
709 | * then restore the new back again */ | 703 | * then restore the new back again */ |
710 | 704 | ||
711 | rx_new = adapter->rx_ring; | ||
712 | tx_new = adapter->tx_ring; | ||
713 | adapter->rx_ring = rx_old; | 705 | adapter->rx_ring = rx_old; |
714 | adapter->tx_ring = tx_old; | 706 | adapter->tx_ring = tx_old; |
715 | e1000_free_all_rx_resources(adapter); | 707 | e1000_free_all_rx_resources(adapter); |
716 | e1000_free_all_tx_resources(adapter); | 708 | e1000_free_all_tx_resources(adapter); |
717 | kfree(tx_old); | 709 | kfree(tx_old); |
718 | kfree(rx_old); | 710 | kfree(rx_old); |
719 | adapter->rx_ring = rx_new; | 711 | adapter->rx_ring = rxdr; |
720 | adapter->tx_ring = tx_new; | 712 | adapter->tx_ring = txdr; |
721 | if ((err = e1000_up(adapter))) | 713 | if ((err = e1000_up(adapter))) |
722 | goto err_setup; | 714 | goto err_setup; |
723 | } | 715 | } |
@@ -729,6 +721,10 @@ err_setup_tx: | |||
729 | err_setup_rx: | 721 | err_setup_rx: |
730 | adapter->rx_ring = rx_old; | 722 | adapter->rx_ring = rx_old; |
731 | adapter->tx_ring = tx_old; | 723 | adapter->tx_ring = tx_old; |
724 | kfree(rxdr); | ||
725 | err_alloc_rx: | ||
726 | kfree(txdr); | ||
727 | err_alloc_tx: | ||
732 | e1000_up(adapter); | 728 | e1000_up(adapter); |
733 | err_setup: | 729 | err_setup: |
734 | clear_bit(__E1000_RESETTING, &adapter->flags); | 730 | clear_bit(__E1000_RESETTING, &adapter->flags); |