forked from mirrors/linux
		
	usb: cdc-acm: fix error handling in acm_probe()
acm_probe() ignores errors in tty_port_register_device() and leaves intfdata pointing to freed memory on alloc_fail7 error path. The patch fixes the both issues. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Acked-by: Oliver Neukum <oliver@neukum.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									d93acbcacd
								
							
						
					
					
						commit
						c93d819550
					
				
					 1 changed files with 17 additions and 2 deletions
				
			
		|  | @ -977,6 +977,8 @@ static int acm_probe(struct usb_interface *intf, | ||||||
| 	int num_rx_buf; | 	int num_rx_buf; | ||||||
| 	int i; | 	int i; | ||||||
| 	int combined_interfaces = 0; | 	int combined_interfaces = 0; | ||||||
|  | 	struct device *tty_dev; | ||||||
|  | 	int rv = -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	/* normal quirks */ | 	/* normal quirks */ | ||||||
| 	quirks = (unsigned long)id->driver_info; | 	quirks = (unsigned long)id->driver_info; | ||||||
|  | @ -1339,11 +1341,24 @@ static int acm_probe(struct usb_interface *intf, | ||||||
| 	usb_set_intfdata(data_interface, acm); | 	usb_set_intfdata(data_interface, acm); | ||||||
| 
 | 
 | ||||||
| 	usb_get_intf(control_interface); | 	usb_get_intf(control_interface); | ||||||
| 	tty_port_register_device(&acm->port, acm_tty_driver, minor, | 	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, | ||||||
| 			&control_interface->dev); | 			&control_interface->dev); | ||||||
|  | 	if (IS_ERR(tty_dev)) { | ||||||
|  | 		rv = PTR_ERR(tty_dev); | ||||||
|  | 		goto alloc_fail8; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | alloc_fail8: | ||||||
|  | 	if (acm->country_codes) { | ||||||
|  | 		device_remove_file(&acm->control->dev, | ||||||
|  | 				&dev_attr_wCountryCodes); | ||||||
|  | 		device_remove_file(&acm->control->dev, | ||||||
|  | 				&dev_attr_iCountryCodeRelDate); | ||||||
|  | 	} | ||||||
|  | 	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); | ||||||
| alloc_fail7: | alloc_fail7: | ||||||
|  | 	usb_set_intfdata(intf, NULL); | ||||||
| 	for (i = 0; i < ACM_NW; i++) | 	for (i = 0; i < ACM_NW; i++) | ||||||
| 		usb_free_urb(acm->wb[i].urb); | 		usb_free_urb(acm->wb[i].urb); | ||||||
| alloc_fail6: | alloc_fail6: | ||||||
|  | @ -1359,7 +1374,7 @@ static int acm_probe(struct usb_interface *intf, | ||||||
| 	acm_release_minor(acm); | 	acm_release_minor(acm); | ||||||
| 	kfree(acm); | 	kfree(acm); | ||||||
| alloc_fail: | alloc_fail: | ||||||
| 	return -ENOMEM; | 	return rv; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void stop_data_traffic(struct acm *acm) | static void stop_data_traffic(struct acm *acm) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Alexey Khoroshilov
						Alexey Khoroshilov