[syzbot] [net?] BUG: sleeping function called from invalid context in team_change_rx_flags

8 views
Skip to first unread message

syzbot

unread,
May 20, 2025, 9:09:36 AM5/20/25
to andrew...@lunn.ch, da...@davemloft.net, edum...@google.com, ho...@kernel.org, ji...@resnulli.us, ku...@kernel.org, kun...@amazon.com, linux-...@vger.kernel.org, net...@vger.kernel.org, pab...@redhat.com, stfom...@gmail.com, syzkall...@googlegroups.com
Hello,

syzbot found the following issue on:

HEAD commit: 239af1970bcb llc: fix data loss when reading from a socket..
git tree: net
console+strace: https://syzkaller.appspot.com/x/log.txt?x=1485bf68580000
kernel config: https://syzkaller.appspot.com/x/.config?x=c3f0e807ec5d1268
dashboard link: https://syzkaller.appspot.com/bug?extid=b191b5ccad8d7a986286
compiler: Debian clang version 20.1.2 (++20250402124445+58df0ef89dd6-1~exp1~20250402004600.97), Debian LLD 20.1.2
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1285bf68580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=12f752d4580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/da0ff1b4efb0/disk-239af197.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/be3cf5250e1a/vmlinux-239af197.xz
kernel image: https://storage.googleapis.com/syzbot-assets/19abc9680c68/bzImage-239af197.xz

The issue was bisected to:

commit 6b1d3c5f675cc794a015138b115afff172fb4c58
Author: Stanislav Fomichev <stfom...@gmail.com>
Date: Wed May 14 22:03:19 2025 +0000

team: grab team lock during team_change_rx_flags

bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1148de70580000
final oops: https://syzkaller.appspot.com/x/report.txt?x=1348de70580000
console output: https://syzkaller.appspot.com/x/log.txt?x=1548de70580000

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+b191b5...@syzkaller.appspotmail.com
Fixes: 6b1d3c5f675c ("team: grab team lock during team_change_rx_flags")

team0: entered promiscuous mode
team_slave_0: entered promiscuous mode
team_slave_1: entered promiscuous mode
team0 (unregistering): left promiscuous mode
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:578
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 5831, name: syz-executor316
preempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
2 locks held by syz-executor316/5831:
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock net/core/rtnetlink.c:80 [inline]
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_net_lock include/linux/rtnetlink.h:130 [inline]
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dellink+0x331/0x710 net/core/rtnetlink.c:3556
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire include/linux/rcupdate.h:331 [inline]
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: rcu_read_lock include/linux/rcupdate.h:841 [inline]
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: packet_notifier+0x78/0xa60 net/packet/af_packet.c:4240
CPU: 0 UID: 0 PID: 5831 Comm: syz-executor316 Not tainted 6.15.0-rc6-syzkaller-00168-g239af1970bcb #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
__might_resched+0x495/0x610 kernel/sched/core.c:8818
__mutex_lock_common kernel/locking/mutex.c:578 [inline]
__mutex_lock+0x106/0xe80 kernel/locking/mutex.c:746
team_change_rx_flags+0x38/0x220 drivers/net/team/team_core.c:1781
dev_change_rx_flags net/core/dev.c:9145 [inline]
__dev_set_promiscuity+0x3f8/0x590 net/core/dev.c:9189
netif_set_promiscuity+0x50/0xe0 net/core/dev.c:9201
dev_set_promiscuity+0x126/0x260 net/core/dev_api.c:286
packet_dev_mc net/packet/af_packet.c:3698 [inline]
packet_dev_mclist_delete net/packet/af_packet.c:3722 [inline]
packet_notifier+0x292/0xa60 net/packet/af_packet.c:4247
notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2214 [inline]
call_netdevice_notifiers net/core/dev.c:2228 [inline]
unregister_netdevice_many_notify+0x15d8/0x2330 net/core/dev.c:11972
rtnl_delete_link net/core/rtnetlink.c:3522 [inline]
rtnl_dellink+0x488/0x710 net/core/rtnetlink.c:3564
rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6955
netlink_rcv_skb+0x219/0x490 net/netlink/af_netlink.c:2534
netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
netlink_unicast+0x75b/0x8d0 net/netlink/af_netlink.c:1339
netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1883
sock_sendmsg_nosec net/socket.c:712 [inline]
__sock_sendmsg+0x219/0x270 net/socket.c:727
____sys_sendmsg+0x505/0x830 net/socket.c:2566
___sys_sendmsg+0x21f/0x2a0 net/socket.c:2620
__sys_sendmsg net/socket.c:2652 [inline]
__do_sys_sendmsg net/socket.c:2657 [inline]
__se_sys_sendmsg net/socket.c:2655 [inline]
__x64_sys_sendmsg+0x19b/0x260 net/socket.c:2655
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa537a5c859
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff93fbcb88 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa537a5c859
RDX: 0000000000000000 RSI: 00002000000001c0 RDI: 0000000000000004
RBP: 00007fa537aaa47d R08: 0000555500000000 R09: 0000555500000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa537aaa3e5
R13: 0000000000000001 R14: 00007fff93fbcbd0 R15: 0000000000000003
</TASK>

=============================
[ BUG: Invalid wait context ]
6.15.0-rc6-syzkaller-00168-g239af1970bcb #0 Tainted: G W
-----------------------------
syz-executor316/5831 is trying to lock:
ffff888076094e00 (team->team_lock_key){+.+.}-{4:4}, at: team_change_rx_flags+0x38/0x220 drivers/net/team/team_core.c:1781
other info that might help us debug this:
context-{5:5}
2 locks held by syz-executor316/5831:
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock net/core/rtnetlink.c:80 [inline]
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_net_lock include/linux/rtnetlink.h:130 [inline]
#0: ffffffff8f2f7408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dellink+0x331/0x710 net/core/rtnetlink.c:3556
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire include/linux/rcupdate.h:331 [inline]
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: rcu_read_lock include/linux/rcupdate.h:841 [inline]
#1: ffffffff8df3dce0 (rcu_read_lock){....}-{1:3}, at: packet_notifier+0x78/0xa60 net/packet/af_packet.c:4240
stack backtrace:
CPU: 0 UID: 0 PID: 5831 Comm: syz-executor316 Tainted: G W 6.15.0-rc6-syzkaller-00168-g239af1970bcb #0 PREEMPT(full)
Tainted: [W]=WARN
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
print_lock_invalid_wait_context kernel/locking/lockdep.c:4831 [inline]
check_wait_context kernel/locking/lockdep.c:4903 [inline]
__lock_acquire+0xbcf/0xd20 kernel/locking/lockdep.c:5185
lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5866
__mutex_lock_common kernel/locking/mutex.c:601 [inline]
__mutex_lock+0x182/0xe80 kernel/locking/mutex.c:746
team_change_rx_flags+0x38/0x220 drivers/net/team/team_core.c:1781
dev_change_rx_flags net/core/dev.c:9145 [inline]
__dev_set_promiscuity+0x3f8/0x590 net/core/dev.c:9189
netif_set_promiscuity+0x50/0xe0 net/core/dev.c:9201
dev_set_promiscuity+0x126/0x260 net/core/dev_api.c:286
packet_dev_mc net/packet/af_packet.c:3698 [inline]
packet_dev_mclist_delete net/packet/af_packet.c:3722 [inline]
packet_notifier+0x292/0xa60 net/packet/af_packet.c:4247
notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2214 [inline]
call_netdevice_notifiers net/core/dev.c:2228 [inline]
unregister_netdevice_many_notify+0x15d8/0x2330 net/core/dev.c:11972
rtnl_delete_link net/core/rtnetlink.c:3522 [inline]
rtnl_dellink+0x488/0x710 net/core/rtnetlink.c:3564
rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6955
netlink_rcv_skb+0x219/0x490 net/netlink/af_netlink.c:2534
netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
netlink_unicast+0x75b/0x8d0 net/netlink/af_netlink.c:1339
netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1883
sock_sendmsg_nosec net/socket.c:712 [inline]
__sock_sendmsg+0x219/0x270 net/socket.c:727
____sys_sendmsg+0x505/0x830 net/socket.c:2566
___sys_sendmsg+0x21f/0x2a0 net/socket.c:2620
__sys_sendmsg net/socket.c:2652 [inline]
__do_sys_sendmsg net/socket.c:2657 [inline]
__se_sys_sendmsg net/socket.c:2655 [inline]
__x64_sys_sendmsg+0x19b/0x260 net/socket.c:2655
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa537a5c859
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff93fbcb88 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa537a5c859
RDX: 0000000000000000 RSI: 00002000000001c0 RDI: 0000000000000004
RBP: 00007fa537aaa47d R08: 0000555500000000 R09: 0000555500000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa537aaa3e5
R13: 0000000000000001 R14: 00007fff93fbcbd0 R15: 0000000000000003
</TASK>
team_slave_0: left promiscuous mode
team_slave_1: left promiscuous mode
team0 (unregistering): Port device team_slave_0 removed
team0 (unregistering): Port device team_slave_1 removed


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
For information about bisection process see: https://goo.gl/tpsmEJ#bisection

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

Stanislav Fomichev

unread,
May 20, 2025, 1:24:37 PM5/20/25
to syzbot, andrew...@lunn.ch, da...@davemloft.net, edum...@google.com, ho...@kernel.org, ji...@resnulli.us, ku...@kernel.org, kun...@amazon.com, linux-...@vger.kernel.org, net...@vger.kernel.org, pab...@redhat.com, syzkall...@googlegroups.com
#syz test

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d4dba06297c3..9148d1aa96f9 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3713,15 +3713,15 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
}

static void packet_dev_mclist_delete(struct net_device *dev,
- struct packet_mclist **mlp)
+ struct packet_mclist **mlp,
+ struct list_head *list)
{
struct packet_mclist *ml;

while ((ml = *mlp) != NULL) {
if (ml->ifindex == dev->ifindex) {
- packet_dev_mc(dev, ml, -1);
+ list_add(&ml->list, list);
*mlp = ml->next;
- kfree(ml);
} else
mlp = &ml->next;
}
@@ -4233,9 +4233,11 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
static int packet_notifier(struct notifier_block *this,
unsigned long msg, void *ptr)
{
- struct sock *sk;
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev);
+ struct packet_mclist *ml, *tmp;
+ LIST_HEAD(mclist);
+ struct sock *sk;

rcu_read_lock();
sk_for_each_rcu(sk, &net->packet.sklist) {
@@ -4244,7 +4246,7 @@ static int packet_notifier(struct notifier_block *this,
switch (msg) {
case NETDEV_UNREGISTER:
if (po->mclist)
- packet_dev_mclist_delete(dev, &po->mclist);
+ packet_dev_mclist_delete(dev, &po->mclist, &mclist);
fallthrough;

case NETDEV_DOWN:
@@ -4277,6 +4279,13 @@ static int packet_notifier(struct notifier_block *this,
}
}
rcu_read_unlock();
+
+ /* packet_dev_mc might grab instance locks so can't run under rcu */
+ list_for_each_entry_safe(ml, tmp, &mclist, list) {
+ packet_dev_mc(dev, ml, -1);
+ kfree(ml);
+ }
+
return NOTIFY_DONE;
}

diff --git a/net/packet/internal.h b/net/packet/internal.h
index d5d70712007a..c7dd55a610db 100644
--- a/net/packet/internal.h
+++ b/net/packet/internal.h
@@ -11,6 +11,7 @@ struct packet_mclist {
unsigned short type;
unsigned short alen;
unsigned char addr[MAX_ADDR_LEN];
+ struct list_head list;
};

/* kbdq - kernel block descriptor queue */

syzbot

unread,
May 20, 2025, 2:18:17 PM5/20/25
to and...@lunn.ch, da...@davemloft.net, edum...@google.com, ho...@kernel.org, ji...@resnulli.us, ku...@kernel.org, kun...@amazon.com, linux-...@vger.kernel.org, net...@vger.kernel.org, pab...@redhat.com, stfom...@gmail.com, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+b191b5...@syzkaller.appspotmail.com
Tested-by: syzbot+b191b5...@syzkaller.appspotmail.com

Tested on:

commit: 9e89db3d Merge tag 'linux-can-fixes-for-6.15-20250520'..
git tree: net
console output: https://syzkaller.appspot.com/x/log.txt?x=158f32d4580000
kernel config: https://syzkaller.appspot.com/x/.config?x=c3f0e807ec5d1268
dashboard link: https://syzkaller.appspot.com/bug?extid=b191b5ccad8d7a986286
compiler: Debian clang version 20.1.2 (++20250402124445+58df0ef89dd6-1~exp1~20250402004600.97), Debian LLD 20.1.2
patch: https://syzkaller.appspot.com/x/patch.diff?x=116b32d4580000

Note: testing is done by a robot and is best-effort only.

Tetsuo Handa

unread,
May 21, 2025, 5:57:56 PM5/21/25
to syzbot+b191b5...@syzkaller.appspotmail.com, syzkaller-bugs
#syz test

diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
index b75ceb90359f..e4e49f8e566f 100644
--- a/drivers/net/team/team_core.c
+++ b/drivers/net/team/team_core.c
@@ -933,7 +933,7 @@ static bool team_port_find(const struct team *team,
* Enable/disable port by adding to enabled port hashlist and setting
* port->index (Might be racy so reader could see incorrect ifindex when
* processing a flying packet, but that is not a problem). Write guarded
- * by team->lock.
+ * by RTNL.
*/
static void team_port_enable(struct team *team,
struct team_port *port)
@@ -1660,8 +1660,6 @@ static int team_init(struct net_device *dev)
goto err_options_register;
netif_carrier_off(dev);

- lockdep_register_key(&team->team_lock_key);
- __mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key);
netdev_lockdep_set_classes(dev);

return 0;
@@ -1682,7 +1680,7 @@ static void team_uninit(struct net_device *dev)
struct team_port *port;
struct team_port *tmp;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
list_for_each_entry_safe(port, tmp, &team->port_list, list)
team_port_del(team, port->dev);

@@ -1691,9 +1689,7 @@ static void team_uninit(struct net_device *dev)
team_mcast_rejoin_fini(team);
team_notify_peers_fini(team);
team_queue_override_fini(team);
- mutex_unlock(&team->lock);
netdev_change_features(dev);
- lockdep_unregister_key(&team->team_lock_key);
}

static void team_destructor(struct net_device *dev)
@@ -1778,7 +1774,7 @@ static void team_change_rx_flags(struct net_device *dev, int change)
struct team_port *port;
int inc;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
list_for_each_entry(port, &team->port_list, list) {
if (change & IFF_PROMISC) {
inc = dev->flags & IFF_PROMISC ? 1 : -1;
@@ -1789,7 +1785,6 @@ static void team_change_rx_flags(struct net_device *dev, int change)
dev_set_allmulti(port->dev, inc);
}
}
- mutex_unlock(&team->lock);
}

static void team_set_rx_mode(struct net_device *dev)
@@ -1811,14 +1806,13 @@ static int team_set_mac_address(struct net_device *dev, void *p)
struct team *team = netdev_priv(dev);
struct team_port *port;

+ ASSERT_RTNL();
if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
dev_addr_set(dev, addr->sa_data);
- mutex_lock(&team->lock);
list_for_each_entry(port, &team->port_list, list)
if (team->ops.port_change_dev_addr)
team->ops.port_change_dev_addr(team, port);
- mutex_unlock(&team->lock);
return 0;
}

@@ -1829,10 +1823,10 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
int err;

/*
- * Alhough this is reader, it's guarded by team lock. It's not possible
+ * Alhough this is reader, it's guarded by RTNL. It's not possible
* to traverse list in reverse under rcu_read_lock
*/
- mutex_lock(&team->lock);
+ ASSERT_RTNL();
team->port_mtu_change_allowed = true;
list_for_each_entry(port, &team->port_list, list) {
err = dev_set_mtu(port->dev, new_mtu);
@@ -1843,7 +1837,6 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
}
}
team->port_mtu_change_allowed = false;
- mutex_unlock(&team->lock);

WRITE_ONCE(dev->mtu, new_mtu);

@@ -1853,7 +1846,6 @@ static int team_change_mtu(struct net_device *dev, int new_mtu)
list_for_each_entry_continue_reverse(port, &team->port_list, list)
dev_set_mtu(port->dev, dev->mtu);
team->port_mtu_change_allowed = false;
- mutex_unlock(&team->lock);

return err;
}
@@ -1904,23 +1896,21 @@ static int team_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
int err;

/*
- * Alhough this is reader, it's guarded by team lock. It's not possible
+ * Alhough this is reader, it's guarded by RTNL. It's not possible
* to traverse list in reverse under rcu_read_lock
*/
- mutex_lock(&team->lock);
+ ASSERT_RTNL();
list_for_each_entry(port, &team->port_list, list) {
err = vlan_vid_add(port->dev, proto, vid);
if (err)
goto unwind;
}
- mutex_unlock(&team->lock);

return 0;

unwind:
list_for_each_entry_continue_reverse(port, &team->port_list, list)
vlan_vid_del(port->dev, proto, vid);
- mutex_unlock(&team->lock);

return err;
}
@@ -1930,10 +1920,9 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
struct team *team = netdev_priv(dev);
struct team_port *port;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
list_for_each_entry(port, &team->port_list, list)
vlan_vid_del(port->dev, proto, vid);
- mutex_unlock(&team->lock);

return 0;
}
@@ -1955,9 +1944,8 @@ static void team_netpoll_cleanup(struct net_device *dev)
{
struct team *team = netdev_priv(dev);

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
__team_netpoll_cleanup(team);
- mutex_unlock(&team->lock);
}

static int team_netpoll_setup(struct net_device *dev)
@@ -1966,7 +1954,7 @@ static int team_netpoll_setup(struct net_device *dev)
struct team_port *port;
int err = 0;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
list_for_each_entry(port, &team->port_list, list) {
err = __team_port_enable_netpoll(port);
if (err) {
@@ -1974,7 +1962,6 @@ static int team_netpoll_setup(struct net_device *dev)
break;
}
}
- mutex_unlock(&team->lock);
return err;
}
#endif
@@ -1985,9 +1972,8 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
struct team *team = netdev_priv(dev);
int err;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
err = team_port_add(team, port_dev, extack);
- mutex_unlock(&team->lock);

if (!err)
netdev_change_features(dev);
@@ -2000,18 +1986,12 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
struct team *team = netdev_priv(dev);
int err;

- mutex_lock(&team->lock);
+ ASSERT_RTNL();
err = team_port_del(team, port_dev);
- mutex_unlock(&team->lock);

if (err)
return err;

- if (netif_is_team_master(port_dev)) {
- lockdep_unregister_key(&team->team_lock_key);
- lockdep_register_key(&team->team_lock_key);
- lockdep_set_class(&team->lock, &team->team_lock_key);
- }
netdev_change_features(dev);

return err;
@@ -2308,6 +2288,7 @@ static struct team *team_nl_team_get(struct genl_info *info)
struct net_device *dev;
struct team *team;

+ ASSERT_RTNL();
if (!info->attrs[TEAM_ATTR_TEAM_IFINDEX])
return NULL;

@@ -2319,13 +2300,12 @@ static struct team *team_nl_team_get(struct genl_info *info)
}

team = netdev_priv(dev);
- mutex_lock(&team->lock);
return team;
}

static void team_nl_team_put(struct team *team)
{
- mutex_unlock(&team->lock);
+ ASSERT_RTNL();
dev_put(team->dev);
}

@@ -2961,11 +2941,8 @@ static void __team_port_change_port_removed(struct team_port *port)

static void team_port_change_check(struct team_port *port, bool linkup)
{
- struct team *team = port->team;
-
- mutex_lock(&team->lock);
+ ASSERT_RTNL();
__team_port_change_check(port, linkup);
- mutex_unlock(&team->lock);
}


diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c
index e0f599e2a51d..4e133451f4d6 100644
--- a/drivers/net/team/team_mode_activebackup.c
+++ b/drivers/net/team/team_mode_activebackup.c
@@ -68,7 +68,7 @@ static void ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx)
struct team_port *active_port;

active_port = rcu_dereference_protected(ab_priv(team)->active_port,
- lockdep_is_held(&team->lock));
+ rtnl_is_locked());
if (active_port)
ctx->data.u32_val = active_port->dev->ifindex;
else
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
index 00f8989c29c0..6f9944108f5a 100644
--- a/drivers/net/team/team_mode_loadbalance.c
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -302,7 +302,7 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
/* Clear old filter data */
__fprog_destroy(lb_priv->ex->orig_fprog);
orig_fp = rcu_dereference_protected(lb_priv->fp,
- lockdep_is_held(&team->lock));
+ rtnl_is_locked());
}

rcu_assign_pointer(lb_priv->fp, fp);
@@ -325,7 +325,7 @@ static void lb_bpf_func_free(struct team *team)

__fprog_destroy(lb_priv->ex->orig_fprog);
fp = rcu_dereference_protected(lb_priv->fp,
- lockdep_is_held(&team->lock));
+ rtnl_is_locked());
bpf_prog_destroy(fp);
}

@@ -336,7 +336,7 @@ static void lb_tx_method_get(struct team *team, struct team_gsetter_ctx *ctx)
char *name;

func = rcu_dereference_protected(lb_priv->select_tx_port_func,
- lockdep_is_held(&team->lock));
+ rtnl_is_locked());
name = lb_select_tx_port_get_name(func);
BUG_ON(!name);
ctx->data.str_val = name;
@@ -478,7 +478,8 @@ static void lb_stats_refresh(struct work_struct *work)
team = lb_priv_ex->team;
lb_priv = get_lb_priv(team);

- if (!mutex_trylock(&team->lock)) {
+ /* This rtnl_trylock() might be easy to compete... */
+ if (!rtnl_trylock()) {
schedule_delayed_work(&lb_priv_ex->stats.refresh_dw, 0);
return;
}
@@ -515,7 +516,7 @@ static void lb_stats_refresh(struct work_struct *work)
schedule_delayed_work(&lb_priv_ex->stats.refresh_dw,
(lb_priv_ex->stats.refresh_interval * HZ) / 10);

- mutex_unlock(&team->lock);
+ rtnl_unlock();
}

static void lb_stats_refresh_interval_get(struct team *team,
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index cdc684e04a2f..ce97d891cf72 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -191,8 +191,6 @@ struct team {

const struct header_ops *header_ops_cache;

- struct mutex lock; /* used for overall locking, e.g. port lists write */
-
/*
* List of enabled ports and their count
*/
@@ -223,7 +221,6 @@ struct team {
atomic_t count_pending;
struct delayed_work dw;
} mcast_rejoin;
- struct lock_class_key team_lock_key;
long mode_priv[TEAM_MODE_PRIV_LONGS];
};

--
2.43.5


syzbot

unread,
May 21, 2025, 8:09:05 PM5/21/25
to linux-...@vger.kernel.org, penguin...@i-love.sakura.ne.jp, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+b191b5...@syzkaller.appspotmail.com
Tested-by: syzbot+b191b5...@syzkaller.appspotmail.com

Tested on:

commit: d83ec0b2 Merge branch 'there-are-some-bugfix-for-hibmc..
git tree: net
console output: https://syzkaller.appspot.com/x/log.txt?x=12c2b9f4580000
kernel config: https://syzkaller.appspot.com/x/.config?x=3dfbdc0d608b70b
dashboard link: https://syzkaller.appspot.com/bug?extid=b191b5ccad8d7a986286
compiler: Debian clang version 20.1.6 (++20250514063057+1e4d39e07757-1~exp1~20250514183223.118), Debian LLD 20.1.6
patch: https://syzkaller.appspot.com/x/patch.diff?x=17b0b9f4580000
Reply all
Reply to author
Forward
0 new messages