aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/korina.c
diff options
context:
space:
mode:
authorPhil Sutter <n0-1@freewrt.org>2009-08-12 08:52:32 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 19:26:12 -0400
commit7010837a44813711b66d9e82e90f9641464e515d (patch)
tree6d6aab73dd5af93db3f3ef1fa69b5e95688171c9 /drivers/net/korina.c
parentf16aea4d201018a124f3c1efd7f247fd3b11e4e1 (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.c12
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
753static void korina_alloc_ring(struct net_device *dev) 753static 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
795static void korina_free_ring(struct net_device *dev) 797static 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 */