lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 22 Jun 2012 18:18:12 +0200
From:	Bjørn Mork <bjorn@...k.no>
To:	Ming Lei <tom.leiming@...il.com>
Cc:	netdev@...r.kernel.org, linux-usb@...r.kernel.org,
	Marius Bjørnstad Kotsbak 
	<marius.kotsbak@...il.com>
Subject: Re: [PATCH net] net: qmi_wwan: fix Oops while disconnecting

Ming Lei <tom.leiming@...il.com> writes:

> Looks I understand the problem incorrectly, your problem is
> that qmi_wwan_cdc_wdm_manage_power is called from
> wdm_open, not from usbnet_open. It is a problem crossing
> 2 class drivers.

That's correct.  Trying to use two drivers at once will necessarily lead
to the situation where one drivers shutdown is called from the other
drivers shutdown.  And the fact that one of the drivers is a usbnet
minidriver complicates this a bit.

But I believe most of it should be OK now.  I tried my best to let the
two drivers share as little as possible.  The only shared state is in
the power management code, which have to access the active/idle state of
both drivers.

>>> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
>>> index e92c057..2eb9e1e 100644
>>> --- a/drivers/net/usb/usbnet.c
>>> +++ b/drivers/net/usb/usbnet.c
>>> @@ -1286,7 +1286,6 @@ void usbnet_disconnect (struct usb_interface *intf)
>>>       struct net_device       *net;
>>>
>>>       dev = usb_get_intfdata(intf);
>>> -     usb_set_intfdata(intf, NULL);
>>>       if (!dev)
>>>               return;
>>
>> I believe that call is there to prevent disconnect from running twice
>> for the common two-interface CDC ethernet model, like e.g. cdc_ether.
>
> No, intfdata is per interface, and .unbind will clear it for each interface.


Yes, intfdata is per interface, but in the case of cdc_ether (and
probably other similar minidrivers) there are two interfaces pointing to
the *same* usbnet private data.

What about the situation where disconnect is called simultaneously for
both interfaces? Or can't that happen? If it can, then we'll do

 driver->disconnect(intf1)                driver->disconnect(intf2)
     dev = usb_get_intfdata(intf1)           dev = usb_get_intfdata(intf2)
     dev->driver_info->unbind()              dev->driver_info->unbind()
     net = dev->net                          net = dev->net
     free_netdev(net)                        free_netdev(dev->net)

where "dev" and "net" will be pointing to the same private data and
netdevice.

I assume that is what the code above is trying to protect against.  But
I could be wrong.  That has happened before, believe it or not :-)


Bjørn
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists