diff options
author | mav <mav@FreeBSD.org> | 2015-10-05 09:04:36 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-10-05 09:04:36 +0000 |
commit | 3844e90a25681f0f831c9e25e2fdd8cfd40fec78 (patch) | |
tree | 959647ee9e70b1602d4712377b47cd7c389ed230 | |
parent | b41248ea28a6823d81f16bdece48b000b6376ef0 (diff) | |
download | FreeBSD-src-3844e90a25681f0f831c9e25e2fdd8cfd40fec78.zip FreeBSD-src-3844e90a25681f0f831c9e25e2fdd8cfd40fec78.tar.gz |
MFC r287715: Improve XCOPY error reporting.
-rw-r--r-- | sys/cam/ctl/ctl_tpc.c | 44 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_tpc_local.c | 3 |
2 files changed, 30 insertions, 17 deletions
diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index f604852..887fe59 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -1589,6 +1589,10 @@ ctl_extended_copy_lid1(struct ctl_scsiio *ctsio) cdb = (struct scsi_extended_copy *)ctsio->cdb; len = scsi_4btoul(cdb->length); + if (len == 0) { + ctl_set_success(ctsio); + goto done; + } if (len < sizeof(struct scsi_extended_copy_lid1_data) || len > sizeof(struct scsi_extended_copy_lid1_data) + TPC_MAX_LIST + TPC_MAX_INLINE) { @@ -1619,20 +1623,22 @@ ctl_extended_copy_lid1(struct ctl_scsiio *ctsio) lencscd = scsi_2btoul(data->cscd_list_length); lenseg = scsi_4btoul(data->segment_list_length); leninl = scsi_4btoul(data->inline_data_length); - if (len < sizeof(struct scsi_extended_copy_lid1_data) + - lencscd + lenseg + leninl || - leninl > TPC_MAX_INLINE) { - ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 0, - /*field*/ 2, /*bit_valid*/ 0, /*bit*/ 0); - goto done; - } if (lencscd > TPC_MAX_CSCDS * sizeof(struct scsi_ec_cscd)) { ctl_set_sense(ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, /*asc*/ 0x26, /*ascq*/ 0x06, SSD_ELEM_NONE); goto done; } - if (lencscd + lenseg > TPC_MAX_LIST) { + if (lenseg > TPC_MAX_SEGS * sizeof(struct scsi_ec_segment)) { + ctl_set_sense(ctsio, /*current_error*/ 1, + /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, + /*asc*/ 0x26, /*ascq*/ 0x08, SSD_ELEM_NONE); + goto done; + } + if (lencscd + lenseg > TPC_MAX_LIST || + leninl > TPC_MAX_INLINE || + len < sizeof(struct scsi_extended_copy_lid1_data) + + lencscd + lenseg + leninl) { ctl_set_param_len_error(ctsio); goto done; } @@ -1716,6 +1722,10 @@ ctl_extended_copy_lid4(struct ctl_scsiio *ctsio) cdb = (struct scsi_extended_copy *)ctsio->cdb; len = scsi_4btoul(cdb->length); + if (len == 0) { + ctl_set_success(ctsio); + goto done; + } if (len < sizeof(struct scsi_extended_copy_lid4_data) || len > sizeof(struct scsi_extended_copy_lid4_data) + TPC_MAX_LIST + TPC_MAX_INLINE) { @@ -1746,20 +1756,22 @@ ctl_extended_copy_lid4(struct ctl_scsiio *ctsio) lencscd = scsi_2btoul(data->cscd_list_length); lenseg = scsi_2btoul(data->segment_list_length); leninl = scsi_2btoul(data->inline_data_length); - if (len < sizeof(struct scsi_extended_copy_lid4_data) + - lencscd + lenseg + leninl || - leninl > TPC_MAX_INLINE) { - ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 0, - /*field*/ 2, /*bit_valid*/ 0, /*bit*/ 0); - goto done; - } if (lencscd > TPC_MAX_CSCDS * sizeof(struct scsi_ec_cscd)) { ctl_set_sense(ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, /*asc*/ 0x26, /*ascq*/ 0x06, SSD_ELEM_NONE); goto done; } - if (lencscd + lenseg > TPC_MAX_LIST) { + if (lenseg > TPC_MAX_SEGS * sizeof(struct scsi_ec_segment)) { + ctl_set_sense(ctsio, /*current_error*/ 1, + /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, + /*asc*/ 0x26, /*ascq*/ 0x08, SSD_ELEM_NONE); + goto done; + } + if (lencscd + lenseg > TPC_MAX_LIST || + leninl > TPC_MAX_INLINE || + len < sizeof(struct scsi_extended_copy_lid1_data) + + lencscd + lenseg + leninl) { ctl_set_param_len_error(ctsio); goto done; } diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c index 7664cb9..5f438af 100644 --- a/sys/cam/ctl/ctl_tpc_local.c +++ b/sys/cam/ctl/ctl_tpc_local.c @@ -281,7 +281,8 @@ tpcl_resolve(struct ctl_softc *softc, int init_port, struct ctl_lun *lun; uint64_t lunid = UINT64_MAX; - if (cscd->type_code != EC_CSCD_ID) + if (cscd->type_code != EC_CSCD_ID || + (cscd->luidt_pdt & EC_LUIDT_MASK) != EC_LUIDT_LUN) return (lunid); cscdid = (struct scsi_ec_cscd_id *)cscd; |