diff options
Diffstat (limited to 'drivers/usb/core/sysfs.c')
| -rw-r--r-- | drivers/usb/core/sysfs.c | 16 | 
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index f98263e21c2a..d83231d6736a 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -1217,14 +1217,24 @@ static ssize_t interface_authorized_store(struct device *dev,  {  	struct usb_interface *intf = to_usb_interface(dev);  	bool val; +	struct kernfs_node *kn;  	if (kstrtobool(buf, &val) != 0)  		return -EINVAL; -	if (val) +	if (val) {  		usb_authorize_interface(intf); -	else -		usb_deauthorize_interface(intf); +	} else { +		/* +		 * Prevent deadlock if another process is concurrently +		 * trying to unregister intf. +		 */ +		kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); +		if (kn) { +			usb_deauthorize_interface(intf); +			sysfs_unbreak_active_protection(kn); +		} +	}  	return count;  }  |