[PATCH v3 3/3] nl80211: wait on udev when creating new device
Jouni Malinen
j at w1.fi
Sat Dec 13 09:12:39 PST 2025
On Wed, Jul 30, 2025 at 02:44:43PM +0200, Benjamin Berg wrote:
> udev/systemd will process new network device. This can result in various
> issues as for example the MAC address may be randomized. Add the
> appropriate integration to wait for the udev "add" event before
> continuing to use the device.
>
> This resolves race conditions when reading the MAC address during
> interface creation (or even changing it right afterwards when creating a
> P2P device).
This does not feel like the correct thing to do, i.e., IMHO,
udev/systemd should not be messing up with those dynamically added
netdevs..
In any case, I applied the first two patches in the series now.
> Enable this feature by default. Systems that do not use udev need to
> explicitly disable it at compile time.
This breaks the build by default on systems that do not include udev
development libraries (including my own development environment). I
don't think this is really the best way of introducing a dependency on a
new library. This should either be enabled by default only if the needed
library files are present on the build system or alternatively, the
build config option should be reversed to not enable this by default but
only when requested.
As far as needing to use libudev in wpa_supplicant is concerned, that
does not feel ideal either. Couldn't this condition be detected based on
kernel events and when detected, starting to adjust processing of the
new interfaces by waiting for their addresses to change?
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> @@ -6242,6 +6245,55 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
> +#ifndef CONFIG_DRIVER_NL80211_DISABLE_UDEV
> + /*
> + * systemd/udev insist on processing new interfaces and may
> + * randomize the MAC address. We need to avoid race conditions between
> + * hostap reading the MAC address and systemd/udev changing it.
> + * Setup a monitor and wait for an event for a "wlan" "net" device
> + * with the expected IFINDEX.
> + * We are guaranteed to receive an event because we install the monitor
> + * before creating it.
> + */
> + struct udev *udev;
> + struct udev_monitor *monitor = NULL;
> +
> + udev = udev_new();
> + if (udev) {
> + struct udev_queue *queue = udev_queue_new(udev);
> +
> + /*
> + * We need to check if udev is running. This is just a long
> + * way of doing an access("/run/udev/control", F_OK);
> + */
Does this really need to be done for every instance of interface
creation? I'd assume udev is either running all the time or not at all,
i.e., it should be sufficient to do this once and remember that for all
following cases when adding an interface.
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list