aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2017-03-17 08:47:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-21 03:31:21 -0400
commitc80c158bfe613d346d48803462bf55d8f35d228e (patch)
tree2f4c3911283a0158a826e9eef63684221a862a35
parent281e36cbaf4395bf036a8301d20906d0fcbdfc72 (diff)
scsi: sr: Sanity check returned mode data
commit a00a7862513089f17209b732f230922f1942e0b9 upstream. Kefeng Wang discovered that old versions of the QEMU CD driver would return mangled mode data causing us to walk off the end of the buffer in an attempt to parse it. Sanity check the returned mode sense data. Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com> Tested-by: Kefeng Wang <wangkefeng.wang@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/scsi/sr.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index bed2bbd6b923..e63597342c96 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -833,6 +833,7 @@ static void get_capabilities(struct scsi_cd *cd)
833 unsigned char *buffer; 833 unsigned char *buffer;
834 struct scsi_mode_data data; 834 struct scsi_mode_data data;
835 struct scsi_sense_hdr sshdr; 835 struct scsi_sense_hdr sshdr;
836 unsigned int ms_len = 128;
836 int rc, n; 837 int rc, n;
837 838
838 static const char *loadmech[] = 839 static const char *loadmech[] =
@@ -859,10 +860,11 @@ static void get_capabilities(struct scsi_cd *cd)
859 scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); 860 scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
860 861
861 /* ask for mode page 0x2a */ 862 /* ask for mode page 0x2a */
862 rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, 863 rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
863 SR_TIMEOUT, 3, &data, NULL); 864 SR_TIMEOUT, 3, &data, NULL);
864 865
865 if (!scsi_status_is_good(rc)) { 866 if (!scsi_status_is_good(rc) || data.length > ms_len ||
867 data.header_length + data.block_descriptor_length > data.length) {
866 /* failed, drive doesn't have capabilities mode page */ 868 /* failed, drive doesn't have capabilities mode page */
867 cd->cdi.speed = 1; 869 cd->cdi.speed = 1;
868 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | 870 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |