Skip to content

Commit c4c2a8f

Browse files
AlanSterngregkh
authored andcommitted
SCSI: fix new bug in scsi_dev_info_list string matching
commit 5e7ff2ca7f2da55fe777167849d0c93403bd0dc8 upstream. Commit b704f70 ("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: b704f70 ("SCSI: fix bug in scsi_dev_info_list matching") Tested-by: Wilfried Klaebe <linux-kernel@lebenslange-mailadresse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent b3a061d commit c4c2a8f

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

drivers/scsi/scsi_devinfo.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
426426
* here, and we don't know what device it is
427427
* trying to work with, leave it as-is.
428428
*/
429-
vmax = 8; /* max length of vendor */
429+
vmax = sizeof(devinfo->vendor);
430430
vskip = vendor;
431431
while (vmax > 0 && *vskip == ' ') {
432432
vmax--;
@@ -436,7 +436,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
436436
while (vmax > 0 && vskip[vmax - 1] == ' ')
437437
--vmax;
438438

439-
mmax = 16; /* max length of model */
439+
mmax = sizeof(devinfo->model);
440440
mskip = model;
441441
while (mmax > 0 && *mskip == ' ') {
442442
mmax--;
@@ -452,10 +452,12 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
452452
* Behave like the older version of get_device_flags.
453453
*/
454454
if (memcmp(devinfo->vendor, vskip, vmax) ||
455-
devinfo->vendor[vmax])
455+
(vmax < sizeof(devinfo->vendor) &&
456+
devinfo->vendor[vmax]))
456457
continue;
457458
if (memcmp(devinfo->model, mskip, mmax) ||
458-
devinfo->model[mmax])
459+
(mmax < sizeof(devinfo->model) &&
460+
devinfo->model[mmax]))
459461
continue;
460462
return devinfo;
461463
} else {

0 commit comments

Comments
 (0)