Validate the packet length reported in the RX CQE before using it as a DMA
sync length or passing it to skb processing. The CQE is supplied by the
NIC device and should not be blindly trusted.

Cc: [email protected]
Reviewed-by: Haiyang Zhang <[email protected]>
Signed-off-by: Dexuan Cui <[email protected]>
---

Changes since v1:
    v1 is split into two patches in the v2.
    Add Haiyang's Reviewed-by.

 drivers/net/ethernet/microsoft/mana/mana_en.c | 24 +++++++++++++++----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c 
b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 1875bffd82b7..0b44c51ae6ec 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -2190,12 +2190,26 @@ static void mana_process_rx_cqe(struct mana_rxq *rxq, 
struct mana_cq *cq,
                rxbuf_oob = &rxq->rx_oobs[curr];
                WARN_ON_ONCE(rxbuf_oob->wqe_inf.wqe_size_in_bu != 1);
 
-               mana_refill_rx_oob(dev, rxq, rxbuf_oob, pktlen, &old_buf, 
&old_fp);
+               if (unlikely(pktlen > rxq->datasize)) {
+                       /* Increase it even if mana_rx_skb() isn't called. */
+                       rxq->rx_cq.work_done++;
 
-               /* Unsuccessful refill will have old_buf == NULL.
-                * In this case, mana_rx_skb() will drop the packet.
-                */
-               mana_rx_skb(old_buf, old_fp, oob, rxq, i);
+                       ++ndev->stats.rx_dropped;
+                       netdev_warn_once(ndev,
+                               "Dropped oversized RX packet: len=%u, 
datasize=%u\n",
+                               pktlen, rxq->datasize);
+
+                       /* Reuse the RX buffer since rxbuf_oob is unchanged. */
+               } else {
+
+                       mana_refill_rx_oob(dev, rxq, rxbuf_oob, pktlen,
+                                          &old_buf, &old_fp);
+
+                       /* Unsuccessful refill will have old_buf == NULL.
+                        * In this case, mana_rx_skb() will drop the packet.
+                        */
+                       mana_rx_skb(old_buf, old_fp, oob, rxq, i);
+               }
 
                mana_move_wq_tail(rxq->gdma_rq,
                                  rxbuf_oob->wqe_inf.wqe_size_in_bu);
-- 
2.34.1


Reply via email to