From 4525b04b23f310d3defbcca2f637f78d9b901a7b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 16 May 2020 16:02:32 +0000 Subject: [PATCH] scst: Reject inconsistent COMPARE AND WRITE commands Reject COMPARE AND WRITE commands if the size of the data buffer does not match the number of logical blocks specified in the CDB. This patch makes two more libiscsi conformance tests pass. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8927 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index da890b9c3..7c4e858bd 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6870,6 +6870,19 @@ out_finish: goto out; } +/* + * The Data-Out Buffer contains two instances of logical block data: + * 1) the compare instance, in which: + * A) the user data is used for the compare operation; and + * B) the protection information, if any, is not used; + * and + * 2) the write instance, in which: + * A) the user data is used for the write operations; and + * B) the protection information, if any, is used for the write operations. + * + * Note: cmd->data_len is half of the DataOut buffer size while cmd->bufflen + * and cmd->expected_transfer_len refer to the entire DataOut buffer. + */ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) { enum scst_exec_res res = SCST_EXEC_COMPLETED; @@ -6913,6 +6926,14 @@ enum scst_exec_res scst_cmp_wr_local(struct scst_cmd *cmd) cwrp->cwr_orig_cmd = cmd; cwrp->cwr_finish_fn = scst_cwr_read_cmd_finished; + if (cmd->bufflen != scst_cmd_get_expected_transfer_len_data(cmd)) { + PRINT_ERROR("COMPARE AND WRITE: data buffer length mismatch (CDB %u <> ini %u)", + cmd->bufflen, + scst_cmd_get_expected_transfer_len_data(cmd)); + scst_set_invalid_field_in_cdb(cmd, 13/*NLB*/, 0); + goto out_done; + } + /* * As required by SBC, DIF PI, if any, is not checked for the read part */