Add bond_xdp_check to ensure the bond interface is in a valid state. syzbot reported WARNING in bond_xdp_get_xmit_slave. In bond_xdp_get_xmit_slave, the comment says /* Should never happen. Mode guarded by bond_xdp_check() */. However, it does not check the status when entering bond_xdp_xmit. Reported-by: syzbot+c187823a52ed505b2257@xxxxxxxxxxxxxxxxxxxxxxxxx Closes: https://syzkaller.appspot.com/bug?extid=c187823a52ed505b2257 Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver") Signed-off-by: Jiwon Kim <jiwonaid0@xxxxxxxxx> --- drivers/net/bonding/bond_main.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bb9c3d6ef435..078c85070b86 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5551,27 +5551,30 @@ bond_xdp_get_xmit_slave(struct net_device *bond_dev, struct xdp_buff *xdp) static int bond_xdp_xmit(struct net_device *bond_dev, int n, struct xdp_frame **frames, u32 flags) { - int nxmit, err = -ENXIO; + struct bonding *bond = netdev_priv(bond_dev); + int nxmit = 0, err = -ENXIO; rcu_read_lock(); - for (nxmit = 0; nxmit < n; nxmit++) { - struct xdp_frame *frame = frames[nxmit]; - struct xdp_frame *frames1[] = {frame}; - struct net_device *slave_dev; - struct xdp_buff xdp; + if (bond_xdp_check(bond)) { + for (nxmit = 0; nxmit < n; nxmit++) { + struct xdp_frame *frame = frames[nxmit]; + struct xdp_frame *frames1[] = {frame}; + struct net_device *slave_dev; + struct xdp_buff xdp; - xdp_convert_frame_to_buff(frame, &xdp); + xdp_convert_frame_to_buff(frame, &xdp); - slave_dev = bond_xdp_get_xmit_slave(bond_dev, &xdp); - if (!slave_dev) { - err = -ENXIO; - break; - } + slave_dev = bond_xdp_get_xmit_slave(bond_dev, &xdp); + if (!slave_dev) { + err = -ENXIO; + break; + } - err = slave_dev->netdev_ops->ndo_xdp_xmit(slave_dev, 1, frames1, flags); - if (err < 1) - break; + err = slave_dev->netdev_ops->ndo_xdp_xmit(slave_dev, 1, frames1, flags); + if (err < 1) + break; + } } rcu_read_unlock(); -- 2.43.0