From: Ben Hutchings <ben@decadent.org.uk>
To: Florian Fainelli <florian@openwrt.org>
Cc: netdev@vger.kernel.org, davem@davemloft.net
Subject: Re: [PATCH net-next 2/2] r6040: use ETH_ZLEN instead of MISR for SKB length checking
Date: Thu, 16 Jan 2014 07:23:21 +0000 [thread overview]
Message-ID: <1389857001.19462.33.camel@deadeye.wl.decadent.org.uk> (raw)
In-Reply-To: <1389819866-32142-3-git-send-email-florian@openwrt.org>
[-- Attachment #1: Type: text/plain, Size: 3766 bytes --]
On Wed, 2014-01-15 at 13:04 -0800, Florian Fainelli wrote:
> Ever since this driver was merged the following code was included:
>
> if (skb->len < MISR)
> skb->len = MISR;
The second 'skb->len' is currently 'descptr->len'.
> MISR is defined to 0x3C which is also equivalent to ETH_ZLEN, but use
> ETH_ZLEN directly which is exactly what we want to be checking for.
>
> Reported-by: Marc Volovic <marcv@ezchip.com>
> Signed-off-by: Florian Fainelli <florian@openwrt.org>
> ---
> drivers/net/ethernet/rdc/r6040.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
> index ff4683a..eb15ebf 100644
> --- a/drivers/net/ethernet/rdc/r6040.c
> +++ b/drivers/net/ethernet/rdc/r6040.c
> @@ -836,8 +836,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
> /* Set TX descriptor & Transmit it */
> lp->tx_free_desc--;
> descptr = lp->tx_insert_ptr;
> - if (skb->len < MISR)
> - descptr->len = MISR;
> + if (skb->len < ETH_ZLEN)
> + descptr->len = ETH_ZLEN;
It looks like this is just increasing the TX descriptor length so the
packet is tail-padded with whatever happens to come next in the skb.
This is absolutely incorrect behaviour and may leak sensitive
information.
Presumably it is necessary to pad the frame because the MAC is too lame
to do it, and the correct way to do that is using skb_padto(skb,
ETH_ZLEN). But this may fail as it might have to allocate memory
Additionally, the driver DMA-maps a length of skb->len but needs to map
a length of descptr->len.
Finally, it doesn't check for failure of DMA mapping.
Tidying up naming should be way down the list of priorities for
fixing this code.
I think this will fix those problems, though I need to split it up into
multiple patches:
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -816,6 +816,7 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
struct r6040_descriptor *descptr;
void __iomem *ioaddr = lp->base;
unsigned long flags;
+ dma_addr_t dma_addr;
/* Critical Section */
spin_lock_irqsave(&lp->lock, flags);
@@ -828,24 +829,35 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- /* Statistic Counter */
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
/* Set TX descriptor & Transmit it */
- lp->tx_free_desc--;
descptr = lp->tx_insert_ptr;
- if (skb->len < MISR)
- descptr->len = MISR;
- else
- descptr->len = skb->len;
+
+ /* MAC doesn't pad frames so we have to */
+ if (skb_padto(skb, ETH_ZLEN)) {
+ kfree_skb(skb);
+ goto out;
+ }
+ descptr->len = max_t(int, skb->len, ETH_ZLEN);
+
+ dma_addr = pci_map_single(lp->pdev, skb->data, descptr->len,
+ PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(lp->pdev, dma_addr)) {
+ kfree_skb(skb);
+ goto out;
+ }
+
+ lp->tx_free_desc--;
descptr->skb_ptr = skb;
- descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
- skb->data, skb->len, PCI_DMA_TODEVICE));
+ descptr->buf = cpu_to_le32(dma_addr);
descptr->status = DSC_OWNER_MAC;
skb_tx_timestamp(skb);
+ /* Statistic Counter */
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+
/* Trigger the MAC to check the TX descriptor */
iowrite16(TM2TX, ioaddr + MTPR);
lp->tx_insert_ptr = descptr->vndescp;
@@ -854,6 +866,7 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
if (!lp->tx_free_desc)
netif_stop_queue(dev);
+out:
spin_unlock_irqrestore(&lp->lock, flags);
return NETDEV_TX_OK;
---
Ben.
--
Ben Hutchings
Quantity is no substitute for quality, but it's the only one we've got.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
next prev parent reply other threads:[~2014-01-16 7:23 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-15 21:04 [PATCH net-next 0/2] r6040: misc fixes Florian Fainelli
2014-01-15 21:04 ` [PATCH net-next 1/2] r6040: add delays in MDIO read/write polling loops Florian Fainelli
2014-01-15 21:04 ` [PATCH net-next 2/2] r6040: use ETH_ZLEN instead of MISR for SKB length checking Florian Fainelli
2014-01-16 7:23 ` Ben Hutchings [this message]
2014-01-16 9:10 ` David Laight
2014-01-16 17:33 ` Ben Hutchings
2014-01-16 19:30 ` Florian Fainelli
2014-01-17 0:24 ` [PATCH net-next 0/2] r6040: misc fixes David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1389857001.19462.33.camel@deadeye.wl.decadent.org.uk \
--to=ben@decadent.org.uk \
--cc=davem@davemloft.net \
--cc=florian@openwrt.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox