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
|
@ -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 New Issue