In drivers/net/ieee802154/cc2520.c and drivers/net/ieee802154/mcr20a.c,
validate the RX frame length byte read from the radio FIFO before
subtracting the 2-byte FCS or allocating/trimming the skb so len < 2
cannot underflow.

Fixes: 0da6bc8cc341 ("ieee802154: cc2520: adds driver for TI CC2520 radio")
Assisted-by: LLM
Signed-off-by: Hui Peng <[email protected]>
---
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
index abfcfe07246a..d2c8484d8fea 100644
--- a/drivers/net/ieee802154/cc2520.c
+++ b/drivers/net/ieee802154/cc2520.c
@@ -482,8 +482,14 @@ cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
         * values on RX. This means we need to manually add the CRC on TX.
         */
        if (priv->promiscuous) {
-               u16 crc = crc_ccitt(0, skb->data, skb->len);
+               u16 crc;
 
+               if (skb_tailroom(skb) < 2 &&
+                   pskb_expand_head(skb, 0, 2, GFP_KERNEL)) {
+                       rc = -ENOMEM;
+                       goto err_tx;
+               }
+               crc = crc_ccitt(0, skb->data, skb->len);
                put_unaligned_le16(crc, skb_put(skb, 2));
                pkt_len = skb->len;
        } else {
@@ -1147,8 +1153,8 @@ static int cc2520_probe(struct spi_device *spi)
        return 0;
 
 err_hw_init:
-       mutex_destroy(&priv->buffer_mutex);
        flush_work(&priv->fifop_irqwork);
+       mutex_destroy(&priv->buffer_mutex);
        return ret;
 }
 
diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c
index 020d392a98b6..d7e076397550 100644
--- a/drivers/net/ieee802154/mcr20a.c
+++ b/drivers/net/ieee802154/mcr20a.c
@@ -790,7 +790,8 @@ mcr20a_handle_rx_read_buf_complete(void *context)
 
        if (!ieee802154_is_valid_psdu_len(len)) {
                dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
-               len = IEEE802154_MTU;
+               mcr20a_request_rx(lp);
+               return;
        }
 
        len = len - 2;  /* get rid of frame check field */
@@ -866,8 +867,7 @@ mcr20a_handle_tx(struct mcr20a_local *lp)
        /* add 2 bytes of FCS */
        lp->tx_len[0]           = lp->tx_skb->len + 2;
        lp->tx_xfer_buf.tx_buf  = lp->tx_skb->data;
-       /* add 1 byte psduLength */
-       lp->tx_xfer_buf.len     = lp->tx_skb->len + 1;
+       lp->tx_xfer_buf.len     = lp->tx_skb->len;
 
        ret = spi_async(lp->spi, &lp->tx_buf_msg);
        if (ret) {

Reply via email to