Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bonding: hold ops lock around get_link

syzbot reports a case of ethtool_ops->get_link being called without
ops lock:

ethtool_op_get_link+0x15/0x60 net/ethtool/ioctl.c:63
bond_check_dev_link+0x1fb/0x4b0 drivers/net/bonding/bond_main.c:864
bond_miimon_inspect drivers/net/bonding/bond_main.c:2734 [inline]
bond_mii_monitor+0x49d/0x3170 drivers/net/bonding/bond_main.c:2956
process_one_work kernel/workqueue.c:3238 [inline]
process_scheduled_works+0xac3/0x18e0 kernel/workqueue.c:3319
worker_thread+0x870/0xd50 kernel/workqueue.c:3400
kthread+0x7b7/0x940 kernel/kthread.c:464
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Commit 04efcee6ef8d ("net: hold instance lock during NETDEV_CHANGE")
changed to lockless __linkwatch_sync_dev in ethtool_op_get_link.
All paths except bonding are coming via locked ioctl. Add necessary
locking to bonding.

Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
Reported-by: syzbot+48c14f61594bdfadb086@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=48c14f61594bdfadb086
Fixes: 04efcee6ef8d ("net: hold instance lock during NETDEV_CHANGE")
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250410161117.3519250-1-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Stanislav Fomichev and committed by
Jakub Kicinski
f7a11cba 52024cd6

+9 -4
+9 -4
drivers/net/bonding/bond_main.c
··· 850 850 struct net_device *slave_dev, int reporting) 851 851 { 852 852 const struct net_device_ops *slave_ops = slave_dev->netdev_ops; 853 - struct ifreq ifr; 854 853 struct mii_ioctl_data *mii; 854 + struct ifreq ifr; 855 + int ret; 855 856 856 857 if (!reporting && !netif_running(slave_dev)) 857 858 return 0; ··· 861 860 return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; 862 861 863 862 /* Try to get link status using Ethtool first. */ 864 - if (slave_dev->ethtool_ops->get_link) 865 - return slave_dev->ethtool_ops->get_link(slave_dev) ? 866 - BMSR_LSTATUS : 0; 863 + if (slave_dev->ethtool_ops->get_link) { 864 + netdev_lock_ops(slave_dev); 865 + ret = slave_dev->ethtool_ops->get_link(slave_dev); 866 + netdev_unlock_ops(slave_dev); 867 + 868 + return ret ? BMSR_LSTATUS : 0; 869 + } 867 870 868 871 /* Ethtool can't be used, fallback to MII ioctls. */ 869 872 if (slave_ops->ndo_eth_ioctl) {