| From stable-bounces@linux.kernel.org Thu Aug 2 10:29:26 2007 |
| From: Alan Stern <stern@rowland.harvard.edu> |
| Date: Thu, 2 Aug 2007 13:29:10 -0400 (EDT) |
| Subject: USB: cdc-acm: fix sysfs attribute registration bug |
| To: Greg KH <greg@kroah.com>, <stable@kernel.org> |
| Cc: Oliver Neukum <oliver@neukum.name>, "A. Kalten" <akalten@comcast.net> |
| Message-ID: <Pine.LNX.4.44L0.0708021324230.2573-100000@iolanthe.rowland.org> |
| |
| From: Alan Stern <stern@rowland.harvard.edu> |
| |
| This patch (as950) fixes a bug in the cdc-acm driver. It doesn't keep |
| track of which interface (control or data) the sysfs attributes get |
| registered for, and as a result, during disconnect it will sometimes |
| attempt to remove the attributes from the wrong interface. The |
| left-over attributes can cause a crash later on, particularly if the driver |
| module has been unloaded. |
| |
| Signed-off-by: Alan Stern <stern@rowland.harvard.edu> |
| CC: Oliver Neukum <oliver@neukum.name> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/usb/class/cdc-acm.c | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/usb/class/cdc-acm.c |
| +++ b/drivers/usb/class/cdc-acm.c |
| @@ -919,6 +919,10 @@ skip_normal_probe: |
| return -EINVAL; |
| } |
| } |
| + |
| + /* Accept probe requests only for the control interface */ |
| + if (intf != control_interface) |
| + return -ENODEV; |
| |
| if (usb_interface_claimed(data_interface)) { /* valid in this context */ |
| dev_dbg(&intf->dev,"The data interface isn't available"); |
| @@ -1107,10 +1111,12 @@ static void acm_disconnect(struct usb_in |
| return; |
| } |
| if (acm->country_codes){ |
| - device_remove_file(&intf->dev, &dev_attr_wCountryCodes); |
| - device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); |
| + device_remove_file(&acm->control->dev, |
| + &dev_attr_wCountryCodes); |
| + device_remove_file(&acm->control->dev, |
| + &dev_attr_iCountryCodeRelDate); |
| } |
| - device_remove_file(&intf->dev, &dev_attr_bmCapabilities); |
| + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); |
| acm->dev = NULL; |
| usb_set_intfdata(acm->control, NULL); |
| usb_set_intfdata(acm->data, NULL); |