[PATCH v2] wpa_supplicant: Denitialize the driver if the last user went away
Lubomir Rintel
lkundrak
Tue Nov 11 05:05:53 PST 2014
On Sat, 2014-11-01 at 17:08 +0200, Jouni Malinen wrote:
> On Thu, Oct 30, 2014 at 09:24:50AM +0100, Lubomir Rintel wrote:
> > It might be that the underlying infrastrucutre went away and the state is no
> > longer valid. We ought to reinitialize it once a device appears again.
> >
> > This is the case when the nl80211 devices disappear and cfg8011 is remoed
> > afterwards. The netlink handle is no longer valid (returns ENOENT) and a new
> > one needs to be open if it's loaded back.
>
> This is not the way the global_init/global_deinit was originally meant
> to be used, i.e., the assumption was more like this getting initialized
> once and then remain available even if no interfaces are enabled, e.g.,
> for get_interfaces() call to work.
I guess this is something specific to Windows NDIS drivers (only one
that seems to implement get_interfaces).
It seems to me that get_interfaces works whether the driver is
initialized or not; maybe it shouldn't even be passwd the global_priv
structure as it's unused anyway?
> > diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
> > @@ -3925,6 +3925,25 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
> > +/* Deinitialize the driver if we're the last user. */
> > +static void wpa_drv_cleanup(struct wpa_supplicant *wpa_s)
> > +{
> > + struct wpa_global *global = wpa_s->global;
> > + struct wpa_supplicant *iface;
> > + int i;
> > +
> > + for (iface = global->ifaces; iface; iface = iface->next)
> > + if (iface != wpa_s && iface->driver == wpa_s->driver)
> > + return;
> > +
> > + for (i = 0; wpa_drivers[i]; i++)
> > + if (global->drv_priv[i] == wpa_s->global_drv_priv)
> > + global->drv_priv[i] = NULL;
> > +
> > + if (wpa_s->driver->global_deinit)
>
> That would be a NULL pointer dereference if interface initialization
> fails early enough (wpa_s->driver == NULL in that case).
I see. Will fix.
> In addition to this, there is something wrong in how the global deinit
> gets handled, i.e., at least one more place can trigger a SIGSEGV when
> running through mac80211_hwsim test cases.
I've run the test suite. It runs now for hours, but I noticed no crashes
so far. However I see a lot of timeout and FAIL messages. I'm wondering
if some tests are expected to fail in master tree, or I need to fix my
setup:
[lkundrak at fedora20-2 hwsim]$ ./run-all.sh
START offchannel_tx_roc_gas 1/764
Exception: ANQP_GET command failed
FAIL offchannel_tx_roc_gas 0.283542 2014-11-11 13:28:00.406416
...
START p2p_device_group_remove 420/764
Exception: [Errno 111] Connection refused
FAIL p2p_device_group_remove 0.104766 2014-11-11 13:58:50.080920
...
> As such, I cannot really
> apply this until those issues have been found and fixed. Then again, I'm
> not sure whether this is really the best way of handling the issue which
> I'm assuming is the main reason for this patch, i.e., need to
> re-initialize some socket for the case of cfg80211 getting reloaded.
Correct. What would be the other possible fix? Address that in kernel?
Lubo
More information about the Hostap
mailing list