bonding: fix lockdep splat in bond_miimon_commit()
authorEric Dumazet <edumazet@google.com>
Tue, 20 Dec 2022 13:08:31 +0000 (13:08 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Jan 2023 11:01:59 +0000 (12:01 +0100)
[ Upstream commit 42c7ded0eeacd2ba5db599205c71c279dc715de7 ]

bond_miimon_commit() is run while RTNL is held, not RCU.

WARNING: suspicious RCU usage
6.1.0-syzkaller-09671-g89529367293c #0 Not tainted
-----------------------------
drivers/net/bonding/bond_main.c:2704 suspicious rcu_dereference_check() usage!

Fixes: e95cc44763a4 ("bonding: do failover when high prio link up")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: Hangbin Liu <liuhangbin@gmail.com>
Cc: Jay Vosburgh <j.vosburgh@gmail.com>
Cc: Veaceslav Falico <vfalico@gmail.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
Link: https://lore.kernel.org/r/20221220130831.1480888-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/bonding/bond_main.c

index b108f2f..fce9301 100644 (file)
@@ -2653,10 +2653,12 @@ static void bond_miimon_link_change(struct bonding *bond,
 
 static void bond_miimon_commit(struct bonding *bond)
 {
-       struct slave *slave, *primary;
+       struct slave *slave, *primary, *active;
        bool do_failover = false;
        struct list_head *iter;
 
+       ASSERT_RTNL();
+
        bond_for_each_slave(bond, slave, iter) {
                switch (slave->link_new_state) {
                case BOND_LINK_NOCHANGE:
@@ -2699,8 +2701,8 @@ static void bond_miimon_commit(struct bonding *bond)
 
                        bond_miimon_link_change(bond, slave, BOND_LINK_UP);
 
-                       if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
-                           slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
+                       active = rtnl_dereference(bond->curr_active_slave);
+                       if (!active || slave == primary || slave->prio > active->prio)
                                do_failover = true;
 
                        continue;