diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2015-07-15 10:55:37 +0300 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-07-23 22:53:05 -0700 |
commit | f5a8b3a796db01b639435515b3adc003b9f27387 (patch) | |
tree | 3ff4e026ec2af94cbef2cef9d365a5faf141059c /drivers/target/target_core_transport.c | |
parent | 12306b425d0dbab7b60f54e02d67cf3dfae494d1 (diff) | |
download | lwn-f5a8b3a796db01b639435515b3adc003b9f27387.tar.gz lwn-f5a8b3a796db01b639435515b3adc003b9f27387.zip |
scsi: Protect against buffer possible overflow in scsi_set_sense_information
Make sure that the input sense buffer has sufficient length
to fit the information descriptor (12 additional bytes).
Modify scsi_set_sense_information to receive the sense buffer
length and adjust its callers scsi target and libata.
(Fix patch fuzz in scsi_set_sense_information - nab)
Reported-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Tejun Heo <tj@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_transport.c')
-rw-r--r-- | drivers/target/target_core_transport.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 2bece607ca0f..7fb031bbcc8d 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2729,7 +2729,7 @@ static const struct sense_info sense_info_table[] = { }, }; -static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) +static int translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) { const struct sense_info *si; u8 *buffer = cmd->sense_buffer; @@ -2756,7 +2756,11 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) scsi_build_sense_buffer(0, buffer, si->key, asc, ascq); if (si->add_sector_info) - scsi_set_sense_information(buffer, cmd->bad_sector); + return scsi_set_sense_information(buffer, + cmd->scsi_sense_length, + cmd->bad_sector); + + return 0; } int @@ -2774,10 +2778,14 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, spin_unlock_irqrestore(&cmd->t_state_lock, flags); if (!from_transport) { + int rc; + cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; - translate_sense_reason(cmd, reason); cmd->scsi_status = SAM_STAT_CHECK_CONDITION; cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; + rc = translate_sense_reason(cmd, reason); + if (rc) + return rc; } trace_target_cmd_complete(cmd); |