diff options
-rw-r--r-- | drivers/ata/libata-scsi.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 307910bd62c3..836947da5b14 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -953,6 +953,9 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
953 | struct ata_taskfile *tf = &qc->tf; | 953 | struct ata_taskfile *tf = &qc->tf; |
954 | const u8 *cdb = scmd->cmnd; | 954 | const u8 *cdb = scmd->cmnd; |
955 | 955 | ||
956 | if (scmd->cmd_len < 5) | ||
957 | goto invalid_fld; | ||
958 | |||
956 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | 959 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; |
957 | tf->protocol = ATA_PROT_NODATA; | 960 | tf->protocol = ATA_PROT_NODATA; |
958 | if (cdb[1] & 0x1) { | 961 | if (cdb[1] & 0x1) { |
@@ -1144,11 +1147,15 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) | |||
1144 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 1147 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
1145 | tf->protocol = ATA_PROT_NODATA; | 1148 | tf->protocol = ATA_PROT_NODATA; |
1146 | 1149 | ||
1147 | if (cdb[0] == VERIFY) | 1150 | if (cdb[0] == VERIFY) { |
1151 | if (scmd->cmd_len < 10) | ||
1152 | goto invalid_fld; | ||
1148 | scsi_10_lba_len(cdb, &block, &n_block); | 1153 | scsi_10_lba_len(cdb, &block, &n_block); |
1149 | else if (cdb[0] == VERIFY_16) | 1154 | } else if (cdb[0] == VERIFY_16) { |
1155 | if (scmd->cmd_len < 16) | ||
1156 | goto invalid_fld; | ||
1150 | scsi_16_lba_len(cdb, &block, &n_block); | 1157 | scsi_16_lba_len(cdb, &block, &n_block); |
1151 | else | 1158 | } else |
1152 | goto invalid_fld; | 1159 | goto invalid_fld; |
1153 | 1160 | ||
1154 | if (!n_block) | 1161 | if (!n_block) |
@@ -1271,12 +1278,16 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |||
1271 | switch (cdb[0]) { | 1278 | switch (cdb[0]) { |
1272 | case READ_10: | 1279 | case READ_10: |
1273 | case WRITE_10: | 1280 | case WRITE_10: |
1281 | if (unlikely(scmd->cmd_len < 10)) | ||
1282 | goto invalid_fld; | ||
1274 | scsi_10_lba_len(cdb, &block, &n_block); | 1283 | scsi_10_lba_len(cdb, &block, &n_block); |
1275 | if (unlikely(cdb[1] & (1 << 3))) | 1284 | if (unlikely(cdb[1] & (1 << 3))) |
1276 | tf_flags |= ATA_TFLAG_FUA; | 1285 | tf_flags |= ATA_TFLAG_FUA; |
1277 | break; | 1286 | break; |
1278 | case READ_6: | 1287 | case READ_6: |
1279 | case WRITE_6: | 1288 | case WRITE_6: |
1289 | if (unlikely(scmd->cmd_len < 6)) | ||
1290 | goto invalid_fld; | ||
1280 | scsi_6_lba_len(cdb, &block, &n_block); | 1291 | scsi_6_lba_len(cdb, &block, &n_block); |
1281 | 1292 | ||
1282 | /* for 6-byte r/w commands, transfer length 0 | 1293 | /* for 6-byte r/w commands, transfer length 0 |
@@ -1287,6 +1298,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |||
1287 | break; | 1298 | break; |
1288 | case READ_16: | 1299 | case READ_16: |
1289 | case WRITE_16: | 1300 | case WRITE_16: |
1301 | if (unlikely(scmd->cmd_len < 16)) | ||
1302 | goto invalid_fld; | ||
1290 | scsi_16_lba_len(cdb, &block, &n_block); | 1303 | scsi_16_lba_len(cdb, &block, &n_block); |
1291 | if (unlikely(cdb[1] & (1 << 3))) | 1304 | if (unlikely(cdb[1] & (1 << 3))) |
1292 | tf_flags |= ATA_TFLAG_FUA; | 1305 | tf_flags |= ATA_TFLAG_FUA; |
@@ -2355,7 +2368,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
2355 | if (ata_check_atapi_dma(qc)) | 2368 | if (ata_check_atapi_dma(qc)) |
2356 | using_pio = 1; | 2369 | using_pio = 1; |
2357 | 2370 | ||
2358 | memcpy(&qc->cdb, scmd->cmnd, dev->cdb_len); | 2371 | memset(qc->cdb, 0, dev->cdb_len); |
2372 | memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len); | ||
2359 | 2373 | ||
2360 | qc->complete_fn = atapi_qc_complete; | 2374 | qc->complete_fn = atapi_qc_complete; |
2361 | 2375 | ||
@@ -2696,6 +2710,13 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, | |||
2696 | { | 2710 | { |
2697 | int rc = 0; | 2711 | int rc = 0; |
2698 | 2712 | ||
2713 | if (unlikely(!scmd->cmd_len)) { | ||
2714 | ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n"); | ||
2715 | scmd->result = DID_ERROR << 16; | ||
2716 | done(scmd); | ||
2717 | return 0; | ||
2718 | } | ||
2719 | |||
2699 | if (dev->class == ATA_DEV_ATA) { | 2720 | if (dev->class == ATA_DEV_ATA) { |
2700 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, | 2721 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, |
2701 | scmd->cmnd[0]); | 2722 | scmd->cmnd[0]); |