Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14e4d57c authored by Aleksandr Miloserdov's avatar Aleksandr Miloserdov Committed by Greg Kroah-Hartman
Browse files

scsi: target: core: Prevent underflow for service actions

[ Upstream commit 14d24e2cc77411301e906a8cf41884739de192de ]

TCM buffer length doesn't necessarily equal 8 + ADDITIONAL LENGTH which
might be considered an underflow in case of Data-In size being greater than
8 + ADDITIONAL LENGTH. So truncate buffer length to prevent underflow.

Link: https://lore.kernel.org/r/20210209072202.41154-3-a.miloserdov@yadro.com


Reviewed-by: default avatarRoman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: default avatarBodo Stroesser <bostroesser@gmail.com>
Signed-off-by: default avatarAleksandr Miloserdov <a.miloserdov@yadro.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 7abc17dc
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -3742,6 +3742,7 @@ core_scsi3_pri_read_keys(struct se_cmd *cmd)
	spin_unlock(&dev->t10_pr.registration_lock);

	put_unaligned_be32(add_len, &buf[4]);
	target_set_cmd_data_length(cmd, 8 + add_len);

	transport_kunmap_data_sg(cmd);

@@ -3760,7 +3761,7 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd)
	struct t10_pr_registration *pr_reg;
	unsigned char *buf;
	u64 pr_res_key;
	u32 add_len = 16; /* Hardcoded to 16 when a reservation is held. */
	u32 add_len = 0;

	if (cmd->data_length < 8) {
		pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
@@ -3778,8 +3779,9 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd)
	pr_reg = dev->dev_pr_res_holder;
	if (pr_reg) {
		/*
		 * Set the hardcoded Additional Length
		 * Set the Additional Length to 16 when a reservation is held
		 */
		add_len = 16;
		put_unaligned_be32(add_len, &buf[4]);

		if (cmd->data_length < 22)
@@ -3815,6 +3817,8 @@ core_scsi3_pri_read_reservation(struct se_cmd *cmd)
			  (pr_reg->pr_res_type & 0x0f);
	}

	target_set_cmd_data_length(cmd, 8 + add_len);

err:
	spin_unlock(&dev->dev_reservation_lock);
	transport_kunmap_data_sg(cmd);
@@ -3833,7 +3837,7 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
	struct se_device *dev = cmd->se_dev;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char *buf;
	u16 add_len = 8; /* Hardcoded to 8. */
	u16 len = 8; /* Hardcoded to 8. */

	if (cmd->data_length < 6) {
		pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
@@ -3845,7 +3849,7 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	put_unaligned_be16(add_len, &buf[0]);
	put_unaligned_be16(len, &buf[0]);
	buf[2] |= 0x10; /* CRH: Compatible Reservation Hanlding bit. */
	buf[2] |= 0x08; /* SIP_C: Specify Initiator Ports Capable bit */
	buf[2] |= 0x04; /* ATP_C: All Target Ports Capable bit */
@@ -3874,6 +3878,8 @@ core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
	buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
	buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */

	target_set_cmd_data_length(cmd, len);

	transport_kunmap_data_sg(cmd);

	return 0;
@@ -4034,6 +4040,7 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
	 * Set ADDITIONAL_LENGTH
	 */
	put_unaligned_be32(add_len, &buf[4]);
	target_set_cmd_data_length(cmd, 8 + add_len);

	transport_kunmap_data_sg(cmd);