summaryrefslogtreecommitdiff
path: root/drivers/target/target_core_xcopy.c
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2017-01-02 18:04:08 +0100
committerBart Van Assche <bart.vanassche@sandisk.com>2017-01-10 08:41:27 -0800
commitf94fd098f674b78c29f482da1999d8de0c93c74e (patch)
treea3d8c3c7bccadd4b9ed6e16fd59ea1e7d69e249c /drivers/target/target_core_xcopy.c
parent66640d35c1e4ef3c96ba5edb3c5e2ff8ab812e7a (diff)
downloadlinux-f94fd098f674b78c29f482da1999d8de0c93c74e.tar.gz
target: check for XCOPY parameter truncation
Check for XCOPY header, CSCD descriptor and segment descriptor list truncation, and respond accordingly. SPC4r37 6.4.1 EXTENDED COPY(LID4) states (also applying to LID1 reqs): If the parameter list length causes truncation of the parameter list, then the copy manager shall transfer no data and shall terminate the EXTENDED COPY command with CHECK CONDITION status, with the sense key set to ILLEGAL REQUEST, and the additional sense code set to PARAMETER LIST LENGTH ERROR. This behaviour can be tested using the libiscsi ExtendedCopy.ParamHdr test. Signed-off-by: David Disseldorp <ddiss@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Diffstat (limited to 'drivers/target/target_core_xcopy.c')
-rw-r--r--drivers/target/target_core_xcopy.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
index 2595c1eb9e91..a9a6462c66d1 100644
--- a/drivers/target/target_core_xcopy.c
+++ b/drivers/target/target_core_xcopy.c
@@ -888,6 +888,12 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
return TCM_UNSUPPORTED_SCSI_OPCODE;
}
+ if (se_cmd->data_length < XCOPY_HDR_LEN) {
+ pr_err("XCOPY parameter truncation: length %u < hdr_len %u\n",
+ se_cmd->data_length, XCOPY_HDR_LEN);
+ return TCM_PARAMETER_LIST_LENGTH_ERROR;
+ }
+
xop = kzalloc(sizeof(struct xcopy_op), GFP_KERNEL);
if (!xop) {
pr_err("Unable to allocate xcopy_op\n");
@@ -923,6 +929,14 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
goto out;
}
+ if (se_cmd->data_length < (XCOPY_HDR_LEN + tdll + sdll + inline_dl)) {
+ pr_err("XCOPY parameter truncation: data length %u too small "
+ "for tdll: %hu sdll: %u inline_dl: %u\n",
+ se_cmd->data_length, tdll, sdll, inline_dl);
+ ret = TCM_PARAMETER_LIST_LENGTH_ERROR;
+ goto out;
+ }
+
pr_debug("Processing XCOPY with list_id: 0x%02x list_id_usage: 0x%02x"
" tdll: %hu sdll: %u inline_dl: %u\n", list_id, list_id_usage,
tdll, sdll, inline_dl);