]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ieee802154: Restore initial state on failed device_rename() in cfg802154_switch_netns()
authorIvan Abramov <i.abramov@mt-integration.ru>
Thu, 3 Apr 2025 10:19:32 +0000 (13:19 +0300)
committerStefan Schmidt <stefan@datenfreihafen.org>
Fri, 19 Jun 2026 19:40:53 +0000 (21:40 +0200)
Currently, the return value of device_rename() is not acted upon.

To avoid an inconsistent state in case of failure, roll back the changes
made before the device_rename() call.

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 66e5c2672cd1 ("ieee802154: add netns support")
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Ivan Abramov <i.abramov@mt-integration.ru>
Link: https://lore.kernel.org/20250403101935.991385-2-i.abramov@mt-integration.ru
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
net/ieee802154/core.c

index 89b671b12600f2dcb5c5aec29e53c562be57dc2e..84d514430e45a5f8fe4b1b369b34bf09ffd50a9a 100644 (file)
@@ -233,31 +233,36 @@ int cfg802154_switch_netns(struct cfg802154_registered_device *rdev,
                wpan_dev->netdev->netns_immutable = true;
        }
 
-       if (err) {
-               /* failed -- clean up to old netns */
-               net = wpan_phy_net(&rdev->wpan_phy);
-
-               list_for_each_entry_continue_reverse(wpan_dev,
-                                                    &rdev->wpan_dev_list,
-                                                    list) {
-                       if (!wpan_dev->netdev)
-                               continue;
-                       wpan_dev->netdev->netns_immutable = false;
-                       err = dev_change_net_namespace(wpan_dev->netdev, net,
-                                                      "wpan%d");
-                       WARN_ON(err);
-                       wpan_dev->netdev->netns_immutable = true;
-               }
-
-               return err;
-       }
-
-       wpan_phy_net_set(&rdev->wpan_phy, net);
+       if (err)
+               goto errout;
 
        err = device_rename(&rdev->wpan_phy.dev, dev_name(&rdev->wpan_phy.dev));
        WARN_ON(err);
 
+       if (err)
+               goto errout;
+
+       wpan_phy_net_set(&rdev->wpan_phy, net);
+
        return 0;
+
+errout:
+       /* failed -- clean up to old netns */
+       net = wpan_phy_net(&rdev->wpan_phy);
+
+       list_for_each_entry_continue_reverse(wpan_dev,
+                                            &rdev->wpan_dev_list,
+                                            list) {
+               if (!wpan_dev->netdev)
+                       continue;
+               wpan_dev->netdev->netns_immutable = false;
+               err = dev_change_net_namespace(wpan_dev->netdev, net,
+                                              "wpan%d");
+               WARN_ON(err);
+               wpan_dev->netdev->netns_immutable = true;
+       }
+
+       return err;
 }
 
 void cfg802154_dev_free(struct cfg802154_registered_device *rdev)