From: Ivan Abramov Date: Thu, 3 Apr 2025 10:19:32 +0000 (+0300) Subject: ieee802154: Restore initial state on failed device_rename() in cfg802154_switch_netns() X-Git-Tag: v7.2-rc1~29^2~74^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2e06b4bef20b59446d5088e938c2be53cc4e6c6;p=thirdparty%2Fkernel%2Flinux.git ieee802154: Restore initial state on failed device_rename() in cfg802154_switch_netns() 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 Signed-off-by: Ivan Abramov Link: https://lore.kernel.org/20250403101935.991385-2-i.abramov@mt-integration.ru Signed-off-by: Stefan Schmidt --- diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 89b671b12600f..84d514430e45a 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -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)