Commit 08f566e8f83b for kernel

commit 08f566e8f83bb70f04ad5aba5be352c490a01c8a
Author: Jesper Dangaard Brouer <hawk@kernel.org>
Date:   Tue May 5 15:21:53 2026 +0200

    veth: fix OOB txq access in veth_poll() with asymmetric queue counts

    XDP redirect into a veth device (via bpf_redirect()) calls
    veth_xdp_xmit(), which enqueues frames into the peer's ptr_ring using
      smp_processor_id() % peer->real_num_rx_queues
    as the ring index.  With an asymmetric veth pair where the peer has
    fewer TX queues than RX queues, that index can exceed
    peer->real_num_tx_queues.

    veth_poll() then resolves peer_txq for the ring via:

      peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;

    where queue_idx = rq->xdp_rxq.queue_index.  When queue_idx exceeds
    peer_dev->real_num_tx_queues this is an out-of-bounds (OOB) access
    into the peer's netdev_queue array, triggering DEBUG_NET_WARN_ON_ONCE
    in netdev_get_tx_queue().

    The normal ndo_start_xmit path is not affected: the stack clamps
    skb->queue_mapping via netdev_cap_txqueue() before invoking
    ndo_start_xmit, so rxq in veth_xmit() never exceeds real_num_tx_queues.

    Fix veth_poll() by clamping: only dereference peer_txq when queue_idx is
    within bounds, otherwise set it to NULL.  The out-of-range rings are fed
    exclusively via XDP redirect (veth_xdp_xmit), never via ndo_start_xmit
    (veth_xmit), so the peer txq was never stopped and there is nothing to
    wake; NULL is the correct fallback.

    Reported-by: Sashiko <sashiko-bot@kernel.org>
    Closes: https://lore.kernel.org/all/20260502071828.616C3C19425@smtp.kernel.org/
    Fixes: dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops")
    Signed-off-by: Jesper Dangaard Brouer <hawk@kernel.org>
    Link: https://patch.msgid.link/20260505132159.241305-2-hawk@kernel.org
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index e35df717e65e..0cfb19b760dd 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -972,7 +972,8 @@ static int veth_poll(struct napi_struct *napi, int budget)

 	/* NAPI functions as RCU section */
 	peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
-	peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;
+	peer_txq = (peer_dev && queue_idx < peer_dev->real_num_tx_queues) ?
+		   netdev_get_tx_queue(peer_dev, queue_idx) : NULL;

 	xdp_set_return_frame_no_direct();
 	done = veth_xdp_rcv(rq, budget, &bq, &stats);