[RHEL7,COMMIT] ms/target: bounds check XCOPY total descriptor list length

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


Message ID 201804031311.w33DBYnb024144@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 974c80aae4c05690946432b0a6133d87cb55eb73
Author: David Disseldorp <ddiss@suse.de>
Date:   Tue Apr 3 16:11:34 2018 +0300

    ms/target: bounds check XCOPY total descriptor list length
    ML: 7d38706669ce00603b187f667a4eb67c94eac098
    spc4r37 states:
      If the combined length of the CSCD descriptors and segment descriptors
      exceeds the allowed value, then the copy manager shall terminate the
      command with CHECK CONDITION status, with the sense key set to ILLEGAL
      REQUEST, and the additional sense code set to PARAMETER LIST LENGTH
    This functionality can be tested using the libiscsi
    ExtendedCopy.DescrLimits 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 | 6 ++++++
 1 file changed, 6 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
index d8d53c4f83b8..f2ea6cc02c26 100644
--- a/drivers/target/target_core_xcopy.c
+++ b/drivers/target/target_core_xcopy.c
@@ -940,6 +940,12 @@  sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
 	tdll = get_unaligned_be16(&p[2]);
 	sdll = get_unaligned_be32(&p[8]);
+	if (tdll + sdll > RCR_OP_MAX_DESC_LIST_LEN) {
+		pr_err("XCOPY descriptor list length %u exceeds maximum %u\n",
+		       tdll + sdll, RCR_OP_MAX_DESC_LIST_LEN);
+		goto out;
+	}
 	inline_dl = get_unaligned_be32(&p[12]);
 	if (inline_dl != 0) {