diff --git a/tcmur_cmd_handler.c b/tcmur_cmd_handler.c index dfffc300..3a07ddac 100644 --- a/tcmur_cmd_handler.c +++ b/tcmur_cmd_handler.c @@ -1161,6 +1161,12 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, { int i, ret; + if (tdll % XCOPY_TARGET_DESC_LEN) { + tcmu_dev_err(udev, + "CSCD descriptor list length %u not a multiple of %u\n", + (unsigned int)tdll, XCOPY_TARGET_DESC_LEN); + return TCMU_STS_NOTSUPP_TGT_DESC_TYPE; + } /* From spc4r36q,section 6.4.3.4 CSCD DESCRIPTOR LIST LENGTH field * If the number of CSCD descriptors exceeds the allowed number, the copy * manager shall terminate the command with CHECK CONDITION status, with @@ -1173,7 +1179,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, return TCMU_STS_TOO_MANY_TGT_DESC; } - for (i = 0; i < RCR_OP_MAX_TARGET_DESC_COUNT; i++) { + for (i = 0; tdll >= XCOPY_TARGET_DESC_LEN; i++) { /* * Only Identification Descriptor Target Descriptor support * for now. @@ -1184,6 +1190,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, return ret; tgt_desc += XCOPY_TARGET_DESC_LEN; + tdll -= XCOPY_TARGET_DESC_LEN; } else { tcmu_dev_err(udev, "Unsupport target descriptor type code 0x%x\n", tgt_desc[0]); @@ -1191,6 +1198,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, } } + ret = TCMU_STS_CP_TGT_DEV_NOTCONN; if (xcopy->src_dev) ret = xcopy_locate_udev(udev->ctx, xcopy->dst_tid_wwn, &xcopy->dst_dev); @@ -1308,6 +1316,12 @@ static int xcopy_parse_parameter_list(struct tcmu_device *dev, * data, after the last segment descriptor. * */ inline_dl = be32toh(*(uint32_t *)&par[12]); + if (inline_dl != 0) { + tcmu_dev_err(dev, "non-zero xcopy inline_dl %u unsupported\n", + inline_dl); + ret = TCMU_STS_INVALID_PARAM_LIST_LEN; + goto err; + } /* From spc4r31, section 6.3.1 EXTENDED COPY command introduction *