airo: Fix read overflows sending packets
authorDan Carpenter <dan.carpenter@oracle.com>
Wed, 27 May 2020 18:48:30 +0000 (21:48 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Jun 2020 07:22:21 +0000 (09:22 +0200)
commit 11e7a91994c29da96d847f676be023da6a2c1359 upstream.

The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from
skb->data even when skb->len is less than ETH_ZLEN so it leads to a read
overflow.

The fix is to pad skb->data to at least ETH_ZLEN bytes.

Cc: <stable@vger.kernel.org>
Reported-by: Hu Jiahui <kirin.say@gmail.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200527184830.GA1164846@mwanda
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/cisco/airo.c

index a8d4700..ea609dc 100644 (file)
@@ -1928,6 +1928,10 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
                airo_print_err(dev->name, "%s: skb == NULL!",__func__);
                return NETDEV_TX_OK;
        }
+       if (skb_padto(skb, ETH_ZLEN)) {
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
+       }
        npacks = skb_queue_len (&ai->txq);
 
        if (npacks >= MAXTXQ - 1) {
@@ -2130,6 +2134,10 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
                airo_print_err(dev->name, "%s: skb == NULL!", __func__);
                return NETDEV_TX_OK;
        }
+       if (skb_padto(skb, ETH_ZLEN)) {
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
+       }
 
        /* Find a vacant FID */
        for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
@@ -2204,6 +2212,10 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
                airo_print_err(dev->name, "%s: skb == NULL!", __func__);
                return NETDEV_TX_OK;
        }
+       if (skb_padto(skb, ETH_ZLEN)) {
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
+       }
 
        /* Find a vacant FID */
        for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );