Skip to content

Commit 08f566e

Browse files
netoptimizerPaolo Abeni
authored andcommitted
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: dc82a33 ("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>
1 parent 593dfd4 commit 08f566e

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

drivers/net/veth.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,8 @@ static int veth_poll(struct napi_struct *napi, int budget)
972972

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

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

0 commit comments

Comments
 (0)