forked from mirrors/linux
		
	SCSI: fix new bug in scsi_dev_info_list string matching
Commitb704f70ce2("SCSI: fix bug in scsi_dev_info_list matching") changed the way vendor- and model-string matching was carried out in the routine that looks up entries in a SCSI devinfo list. The new matching code failed to take into account the case of a maximum-length string; in such cases it could end up testing for a terminating '\0' byte beyond the end of the memory allocated to the string. This out-of-bounds bug was detected by UBSAN. I don't know if anybody has actually encountered this bug. The symptom would be that a device entry in the blacklist might not be matched properly if it contained an 8-character vendor name or a 16-character model name. Such entries certainly exist in scsi_static_device_list. This patch fixes the problem by adding a check for a maximum-length string before the '\0' test. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Fixes:b704f70ce2("SCSI: fix bug in scsi_dev_info_list matching") Tested-by: Wilfried Klaebe <linux-kernel@lebenslange-mailadresse.de> CC: <stable@vger.kernel.org> # v4.4+ Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
		
							parent
							
								
									54e430bbd4
								
							
						
					
					
						commit
						5e7ff2ca7f
					
				
					 1 changed files with 6 additions and 4 deletions
				
			
		|  | @ -429,7 +429,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, | ||||||
| 	 * here, and we don't know what device it is | 	 * here, and we don't know what device it is | ||||||
| 	 * trying to work with, leave it as-is. | 	 * trying to work with, leave it as-is. | ||||||
| 	 */ | 	 */ | ||||||
| 	vmax = 8;	/* max length of vendor */ | 	vmax = sizeof(devinfo->vendor); | ||||||
| 	vskip = vendor; | 	vskip = vendor; | ||||||
| 	while (vmax > 0 && *vskip == ' ') { | 	while (vmax > 0 && *vskip == ' ') { | ||||||
| 		vmax--; | 		vmax--; | ||||||
|  | @ -439,7 +439,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, | ||||||
| 	while (vmax > 0 && vskip[vmax - 1] == ' ') | 	while (vmax > 0 && vskip[vmax - 1] == ' ') | ||||||
| 		--vmax; | 		--vmax; | ||||||
| 
 | 
 | ||||||
| 	mmax = 16;	/* max length of model */ | 	mmax = sizeof(devinfo->model); | ||||||
| 	mskip = model; | 	mskip = model; | ||||||
| 	while (mmax > 0 && *mskip == ' ') { | 	while (mmax > 0 && *mskip == ' ') { | ||||||
| 		mmax--; | 		mmax--; | ||||||
|  | @ -455,10 +455,12 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, | ||||||
| 			 * Behave like the older version of get_device_flags. | 			 * Behave like the older version of get_device_flags. | ||||||
| 			 */ | 			 */ | ||||||
| 			if (memcmp(devinfo->vendor, vskip, vmax) || | 			if (memcmp(devinfo->vendor, vskip, vmax) || | ||||||
| 					devinfo->vendor[vmax]) | 					(vmax < sizeof(devinfo->vendor) && | ||||||
|  | 						devinfo->vendor[vmax])) | ||||||
| 				continue; | 				continue; | ||||||
| 			if (memcmp(devinfo->model, mskip, mmax) || | 			if (memcmp(devinfo->model, mskip, mmax) || | ||||||
| 					devinfo->model[mmax]) | 					(mmax < sizeof(devinfo->model) && | ||||||
|  | 						devinfo->model[mmax])) | ||||||
| 				continue; | 				continue; | ||||||
| 			return devinfo; | 			return devinfo; | ||||||
| 		} else { | 		} else { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Alan Stern
						Alan Stern