Thread (3 messages) 3 messages, 3 authors, 2026-03-26
STALE67d

[PATCH] qede: validate TPA aggregation indices from CQEs

From: Pengpeng Hou <hidden>
Date: 2026-03-23 07:24:31
Also in: lkml
Subsystem: networking drivers, qlogic ql4xxx ethernet driver, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

The fast-path TPA handlers index rxq->tpa_info[] directly with the
completion-provided tpa_agg_index field. That field is only a raw u8 in
the CQE layout, while rxq->tpa_info has ETH_TPA_MAX_AGGS_NUM entries.

Reject out-of-range indices before touching rxq->tpa_info[] and recycle
the affected receive BDs instead of indexing past the fixed aggregation
state array.

Signed-off-by: Pengpeng Hou <redacted>
---
 drivers/net/ethernet/qlogic/qede/qede_fp.c | 59 ++++++++++++++++++++--
 1 file changed, 54 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index e338bfc8b7b2..85d640de5f21 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -668,8 +668,18 @@ static int qede_fill_frag_skb(struct qede_dev *edev,
 {
 	struct sw_rx_data *current_bd = &rxq->sw_rx_ring[rxq->sw_rx_cons &
 							 NUM_RX_BDS_MAX];
-	struct qede_agg_info *tpa_info = &rxq->tpa_info[tpa_agg_index];
-	struct sk_buff *skb = tpa_info->skb;
+	struct qede_agg_info *tpa_info;
+	struct sk_buff *skb;
+
+	if (unlikely(tpa_agg_index >= ARRAY_SIZE(rxq->tpa_info))) {
+		DP_NOTICE(edev, "TPA aggregation index %u out of range\n",
+			  tpa_agg_index);
+		qede_recycle_rx_bd_ring(rxq, 1);
+		return -EINVAL;
+	}
+
+	tpa_info = &rxq->tpa_info[tpa_agg_index];
+	skb = tpa_info->skb;
 
 	if (unlikely(tpa_info->state != QEDE_AGG_STATE_START))
 		goto out;
@@ -833,10 +843,26 @@ static void qede_tpa_start(struct qede_dev *edev,
 			   struct qede_rx_queue *rxq,
 			   struct eth_fast_path_rx_tpa_start_cqe *cqe)
 {
-	struct qede_agg_info *tpa_info = &rxq->tpa_info[cqe->tpa_agg_index];
+	struct qede_agg_info *tpa_info;
 	struct sw_rx_data *sw_rx_data_cons;
+	u8 agg_index = cqe->tpa_agg_index;
+	u8 num_bds = 1;
 	u16 pad;
 
+	if (cqe->bw_ext_bd_len_list[0])
+		num_bds++;
+	if (cqe->bw_ext_bd_len_list[1])
+		num_bds++;
+
+	if (unlikely(agg_index >= ARRAY_SIZE(rxq->tpa_info))) {
+		DP_NOTICE(edev, "TPA aggregation index %u out of range\n",
+			  agg_index);
+		qede_recycle_rx_bd_ring(rxq, num_bds);
+		return;
+	}
+
+	tpa_info = &rxq->tpa_info[agg_index];
+
 	sw_rx_data_cons = &rxq->sw_rx_ring[rxq->sw_rx_cons & NUM_RX_BDS_MAX];
 	pad = cqe->placement_offset + rxq->rx_headroom;
 
@@ -876,7 +902,7 @@ static void qede_tpa_start(struct qede_dev *edev,
 
 cons_buf: /* We still need to handle bd_len_list to consume buffers */
 	if (likely(cqe->bw_ext_bd_len_list[0]))
-		qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
+		qede_fill_frag_skb(edev, rxq, agg_index,
 				   le16_to_cpu(cqe->bw_ext_bd_len_list[0]));
 
 	if (unlikely(cqe->bw_ext_bd_len_list[1])) {
@@ -960,9 +986,21 @@ static inline void qede_tpa_cont(struct qede_dev *edev,
 				 struct eth_fast_path_rx_tpa_cont_cqe *cqe)
 {
 	int i;
+	u8 agg_index = cqe->tpa_agg_index;
+
+	if (unlikely(agg_index >= ARRAY_SIZE(rxq->tpa_info))) {
+		DP_NOTICE(edev, "TPA aggregation index %u out of range\n",
+			  agg_index);
+
+		for (i = 0; cqe->len_list[i] &&
+		     i < ARRAY_SIZE(cqe->len_list); i++)
+			qede_recycle_rx_bd_ring(rxq, 1);
+
+		return;
+	}
 
 	for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++)
-		qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
+		qede_fill_frag_skb(edev, rxq, agg_index,
 				   le16_to_cpu(cqe->len_list[i]));
 
 	if (unlikely(i > 1))
@@ -979,6 +1017,17 @@ static int qede_tpa_end(struct qede_dev *edev,
 	struct sk_buff *skb;
 	int i;
 
+	if (unlikely(cqe->tpa_agg_index >= ARRAY_SIZE(rxq->tpa_info))) {
+		DP_NOTICE(edev, "TPA aggregation index %u out of range\n",
+			  cqe->tpa_agg_index);
+
+		for (i = 0; cqe->len_list[i] &&
+		     i < ARRAY_SIZE(cqe->len_list); i++)
+			qede_recycle_rx_bd_ring(rxq, 1);
+
+		return 0;
+	}
+
 	tpa_info = &rxq->tpa_info[cqe->tpa_agg_index];
 	skb = tpa_info->skb;
 
-- 
2.50.1 (Apple Git-155)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help