diff options
author | Phil Sutter <n0-1@freewrt.org> | 2009-08-12 08:52:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-13 19:26:12 -0400 |
commit | 7010837a44813711b66d9e82e90f9641464e515d (patch) | |
tree | 6d6aab73dd5af93db3f3ef1fa69b5e95688171c9 /drivers/net/korina.c | |
parent | f16aea4d201018a124f3c1efd7f247fd3b11e4e1 (diff) |
korina: add error-handling to korina_alloc_ring
This also avoids a potential buffer overflow in case the very first
receive descriptor fails to allocate, as an index of -1 would be used
afterwards. Kudos to Roel Kluin for pointing this out and providing an
initial patch.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/korina.c')
-rw-r--r-- | drivers/net/korina.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 6df9d253cc0a..51ca54c8ec57 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c | |||
@@ -750,7 +750,7 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
750 | .get_link = netdev_get_link, | 750 | .get_link = netdev_get_link, |
751 | }; | 751 | }; |
752 | 752 | ||
753 | static void korina_alloc_ring(struct net_device *dev) | 753 | static int korina_alloc_ring(struct net_device *dev) |
754 | { | 754 | { |
755 | struct korina_private *lp = netdev_priv(dev); | 755 | struct korina_private *lp = netdev_priv(dev); |
756 | struct sk_buff *skb; | 756 | struct sk_buff *skb; |
@@ -771,7 +771,7 @@ static void korina_alloc_ring(struct net_device *dev) | |||
771 | for (i = 0; i < KORINA_NUM_RDS; i++) { | 771 | for (i = 0; i < KORINA_NUM_RDS; i++) { |
772 | skb = dev_alloc_skb(KORINA_RBSIZE + 2); | 772 | skb = dev_alloc_skb(KORINA_RBSIZE + 2); |
773 | if (!skb) | 773 | if (!skb) |
774 | break; | 774 | return -ENOMEM; |
775 | skb_reserve(skb, 2); | 775 | skb_reserve(skb, 2); |
776 | lp->rx_skb[i] = skb; | 776 | lp->rx_skb[i] = skb; |
777 | lp->rd_ring[i].control = DMA_DESC_IOD | | 777 | lp->rd_ring[i].control = DMA_DESC_IOD | |
@@ -790,6 +790,8 @@ static void korina_alloc_ring(struct net_device *dev) | |||
790 | lp->rx_chain_head = 0; | 790 | lp->rx_chain_head = 0; |
791 | lp->rx_chain_tail = 0; | 791 | lp->rx_chain_tail = 0; |
792 | lp->rx_chain_status = desc_empty; | 792 | lp->rx_chain_status = desc_empty; |
793 | |||
794 | return 0; | ||
793 | } | 795 | } |
794 | 796 | ||
795 | static void korina_free_ring(struct net_device *dev) | 797 | static void korina_free_ring(struct net_device *dev) |
@@ -832,7 +834,11 @@ static int korina_init(struct net_device *dev) | |||
832 | writel(ETH_INT_FC_EN, &lp->eth_regs->ethintfc); | 834 | writel(ETH_INT_FC_EN, &lp->eth_regs->ethintfc); |
833 | 835 | ||
834 | /* Allocate rings */ | 836 | /* Allocate rings */ |
835 | korina_alloc_ring(dev); | 837 | if (korina_alloc_ring(dev)) { |
838 | printk(KERN_ERR "%s: descriptor allocation failed\n", dev->name); | ||
839 | korina_free_ring(dev); | ||
840 | return -ENOMEM; | ||
841 | } | ||
836 | 842 | ||
837 | writel(0, &lp->rx_dma_regs->dmas); | 843 | writel(0, &lp->rx_dma_regs->dmas); |
838 | /* Start Rx DMA */ | 844 | /* Start Rx DMA */ |