From patchwork Tue Aug 18 08:50:34 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: roel kluin X-Patchwork-Id: 31552 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id C1782B6F20 for ; Tue, 18 Aug 2009 18:51:40 +1000 (EST) Received: by ozlabs.org (Postfix) id B3752DDD1B; Tue, 18 Aug 2009 18:51:40 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 3A4D1DDD01 for ; Tue, 18 Aug 2009 18:51:40 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757889AbZHRIvV (ORCPT ); Tue, 18 Aug 2009 04:51:21 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757309AbZHRIvV (ORCPT ); Tue, 18 Aug 2009 04:51:21 -0400 Received: from mail-ew0-f207.google.com ([209.85.219.207]:46833 "EHLO mail-ew0-f207.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757303AbZHRIvU (ORCPT ); Tue, 18 Aug 2009 04:51:20 -0400 X-Greylist: delayed 308 seconds by postgrey-1.27 at vger.kernel.org; Tue, 18 Aug 2009 04:51:19 EDT Received: by ewy3 with SMTP id 3so1399979ewy.18 for ; Tue, 18 Aug 2009 01:51:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=e7slzSZsW7hOdCng6nXkdCUXUo5ba2WNttLU4NH5C4Q=; b=bOaB3mTV4jNb+D2r6Hi8qecvZaJ13Ts4/yzkvQZNZybFTmtuavKEYMllVrVhmFzIh/ L2Mfjuc0eB4W0ZNTgRzl0s68vl2cJtOkZdJOIxeQg9M7vfuFjU4t4leGMb9F+qdA1P6V WctIWy/rj/HWzqRMwsvP5L241tskFkJjO9MUU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=YQkdwxlsED8wD18N4YwcP3pa4TyezJP71Y5U7xiU0BBno4EUJKEK8+SD3BE45tXV3R wIA2rJNvB1gofz64stm4r89GrhZPFwUauu125F9fMyP30Qo6AwXCmyOm7LY3I21efTIp HjnLZBO5bmd4tz8qEz1jxXosQHngp+rVR+1jk= Received: by 10.216.47.196 with SMTP id t46mr1165111web.121.1250585171269; Tue, 18 Aug 2009 01:46:11 -0700 (PDT) Received: from zoinx.mars (d133062.upc-d.chello.nl [213.46.133.62]) by mx.google.com with ESMTPS id t12sm6739554gvd.16.2009.08.18.01.46.06 (version=SSLv3 cipher=RC4-MD5); Tue, 18 Aug 2009 01:46:08 -0700 (PDT) Message-ID: <4A8A6B5A.7030104@gmail.com> Date: Tue, 18 Aug 2009 10:50:34 +0200 From: Roel Kluin User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090814 Fedora/3.0-2.6.b3.fc11 Thunderbird/3.0b3 MIME-Version: 1.0 To: David Miller CC: netdev@vger.kernel.org, akpm@linux-foundation.org Subject: Re: [PATCH] yellowfin: Fix buffer underrun after dev_alloc_skb() failure References: <4A7C6B08.1040800@gmail.com> <20090812.210845.84504668.davem@davemloft.net> <4A853572.70209@gmail.com> <20090814.161701.02803885.davem@davemloft.net> In-Reply-To: <20090814.161701.02803885.davem@davemloft.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org yellowfin_init_ring() needs to clean up if dev_alloc_skb() fails and should pass an error status up to the caller. This also prevents an buffer underrun if failure occurred in the first iteration. yellowfin_open() which calls yellowfin_init_ring() should free its requested irq upon failure. Signed-off-by: Roel Kluin --- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index a075801..c2fd618 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int yellowfin_open(struct net_device *dev); static void yellowfin_timer(unsigned long data); static void yellowfin_tx_timeout(struct net_device *dev); -static void yellowfin_init_ring(struct net_device *dev); +static int yellowfin_init_ring(struct net_device *dev); static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); static int yellowfin_rx(struct net_device *dev); @@ -573,19 +573,24 @@ static int yellowfin_open(struct net_device *dev) { struct yellowfin_private *yp = netdev_priv(dev); void __iomem *ioaddr = yp->base; - int i; + int i, ret; /* Reset the chip. */ iowrite32(0x80000000, ioaddr + DMACtrl); - i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); - if (i) return i; + ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); + if (ret) + return ret; if (yellowfin_debug > 1) printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", dev->name, dev->irq); - yellowfin_init_ring(dev); + ret = yellowfin_init_ring(dev); + if (ret) { + free_irq(dev->irq, dev); + return ret; + } iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); @@ -725,10 +730,10 @@ static void yellowfin_tx_timeout(struct net_device *dev) } /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void yellowfin_init_ring(struct net_device *dev) +static int yellowfin_init_ring(struct net_device *dev) { struct yellowfin_private *yp = netdev_priv(dev); - int i; + int i, j; yp->tx_full = 0; yp->cur_rx = yp->cur_tx = 0; @@ -753,6 +758,11 @@ static void yellowfin_init_ring(struct net_device *dev) yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } + if (i != RX_RING_SIZE) { + for (j = 0; j < i; j++) + dev_kfree_skb(yp->rx_skbuff[j]); + return -ENOMEM; + } yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -769,8 +779,6 @@ static void yellowfin_init_ring(struct net_device *dev) yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); #else { - int j; - /* Tx ring needs a pair of descriptors, the second for the status. */ for (i = 0; i < TX_RING_SIZE; i++) { j = 2*i; @@ -805,7 +813,7 @@ static void yellowfin_init_ring(struct net_device *dev) } #endif yp->tx_tail_desc = &yp->tx_status[0]; - return; + return 0; } static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)