summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2024-03-21 09:45:15 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2024-03-26 10:26:02 +0100
commitde130df3e2207dc015c4fa82ecf766be2851532c (patch)
treeb58df09e5722008ad2be1899819523cb8e6620d3
parent666dd2840a305ada4d721e84700fda284295188b (diff)
manager: fix race condition while enumerating devices at startupbg/link-rename-race-rhel25808
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
-rw-r--r--src/core/nm-manager.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index f607569d88..c30a2ff632 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -4438,10 +4438,25 @@ platform_query_devices(NMManager *self)
links = nm_platform_link_get_all(priv->platform);
if (!links)
return;
+
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;
+ /*
+ * @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);
platform_link_added(self,
link->ifindex,