Skip to content

Commit 9337c54

Browse files
netoptimizerkuba-moo
authored andcommitted
veth: prevent NULL pointer dereference in veth_xdp_rcv
The veth peer device is RCU protected, but when the peer device gets deleted (veth_dellink) then the pointer is assigned NULL (via RCU_INIT_POINTER). This patch adds a necessary NULL check in veth_xdp_rcv when accessing the veth peer net_device. This fixes a bug introduced in commit dc82a33 ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops"). The bug is a race and only triggers when having inflight packets on a veth that is being deleted. Reported-by: Ihor Solodrai <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Reported-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Fixes: dc82a33 ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops") Signed-off-by: Jesper Dangaard Brouer <[email protected]> Acked-by: Ihor Solodrai <[email protected]> Link: https://patch.msgid.link/174964557873.519608.10855046105237280978.stgit@firesoul Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a844b0c commit 9337c54

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/net/veth.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
909909

910910
/* NAPI functions as RCU section */
911911
peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held());
912-
peer_txq = netdev_get_tx_queue(peer_dev, queue_idx);
912+
peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL;
913913

914914
for (i = 0; i < budget; i++) {
915915
void *ptr = __ptr_ring_consume(&rq->xdp_ring);
@@ -959,7 +959,7 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget,
959959
rq->stats.vs.xdp_packets += done;
960960
u64_stats_update_end(&rq->stats.syncp);
961961

962-
if (unlikely(netif_tx_queue_stopped(peer_txq)))
962+
if (peer_txq && unlikely(netif_tx_queue_stopped(peer_txq)))
963963
netif_tx_wake_queue(peer_txq);
964964

965965
return done;

0 commit comments

Comments
 (0)