[RHEL7,COMMIT] ms/target: check for XCOPY parameter truncation

Submitted by Konstantin Khorenko on April 3, 2018, 1:11 p.m.

Details

Message ID 201804031311.w33DBYue024195@finist_ce7.work
State New
Series "target: backport bug fixes for XCOPY"
Headers show

Commit Message

Konstantin Khorenko April 3, 2018, 1:11 p.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.46.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.46.3
------>
commit 6a85a0b302c9e590795cb7eb09c0c4fcaeb12798
Author: David Disseldorp <ddiss@suse.de>
Date:   Tue Apr 3 16:11:34 2018 +0300

    ms/target: check for XCOPY parameter truncation
    
    ML: f94fd098f674b78c29f482da1999d8de0c93c74e
    
    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>
    Signed-off-by: Andrei Vagin <avagin@openvz.org>
---
 drivers/target/target_core_xcopy.c | 14 ++++++++++++++
 drivers/target/target_core_xcopy.h |  1 +
 2 files changed, 15 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
index f2ea6cc02c26..3ac8c4557a6d 100644
--- a/drivers/target/target_core_xcopy.c
+++ b/drivers/target/target_core_xcopy.c
@@ -918,6 +918,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");
@@ -953,6 +959,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);
diff --git a/drivers/target/target_core_xcopy.h b/drivers/target/target_core_xcopy.h
index 700a981c7b41..b5baeccfc8eb 100644
--- a/drivers/target/target_core_xcopy.h
+++ b/drivers/target/target_core_xcopy.h
@@ -1,3 +1,4 @@ 
+#define XCOPY_HDR_LEN			16
 #define XCOPY_TARGET_DESC_LEN		32
 #define XCOPY_SEGMENT_DESC_LEN		28
 #define XCOPY_NAA_IEEE_REGEX_LEN	16