manager: fix race condition while enumerating devices at startup
While enumerating devices at startup, we take a snapshot of existing links from platform and we start creating device instances for them. It's possible that in the meantime, while processing netlink events in platform_link_added(), a link gets renamed. If that happens, then we have two different views of the same ifindex: the cached link from `links` and the link in platform. This can cause issues: in platform_link_added() we create the device with the cached name; then in NMDevice's constructor(), we look up from platform the ifindex for the given name. Because of the rename, this lookup can match a newly created, different link. The end result is that the ifindex from the initial snapshot doesn't get a NMDevice and is not handled by NetworkManager. Fix this problem by fetching the latest version of the link from platform to make sure we have a consistent view of the state. https://issues.redhat.com/browse/RHEL-25808 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1897
This commit is contained in:
@@ -4438,10 +4438,25 @@ platform_query_devices(NMManager *self)
|
|||||||
links = nm_platform_link_get_all(priv->platform);
|
links = nm_platform_link_get_all(priv->platform);
|
||||||
if (!links)
|
if (!links)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < links->len; i++) {
|
for (i = 0; i < links->len; i++) {
|
||||||
const NMPlatformLink *link = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
const NMPlatformLink *elem = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
||||||
|
const NMPlatformLink *link;
|
||||||
const NMConfigDeviceStateData *dev_state;
|
const NMConfigDeviceStateData *dev_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @links is an immutable snapshot of the platform links captured before
|
||||||
|
* the loop was started. It's possible that in the meantime, while
|
||||||
|
* processing netlink events in platform_link_added(), a link was
|
||||||
|
* renamed. If that happens, we have 2 different views of the same
|
||||||
|
* ifindex: the one from @links and the one from platform. This can
|
||||||
|
* cause race conditions; make sure to use the latest known version of
|
||||||
|
* the link.
|
||||||
|
*/
|
||||||
|
link = nm_platform_link_get(priv->platform, elem->ifindex);
|
||||||
|
if (!link)
|
||||||
|
continue;
|
||||||
|
|
||||||
dev_state = nm_config_device_state_get(priv->config, link->ifindex);
|
dev_state = nm_config_device_state_get(priv->config, link->ifindex);
|
||||||
platform_link_added(self,
|
platform_link_added(self,
|
||||||
link->ifindex,
|
link->ifindex,
|
||||||
|
Reference in New Issue
Block a user