diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-08-10 03:59:58 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-08-22 15:26:26 -0400 |
commit | 01cde4d54327884a0b61ce8666092f5703557d4b (patch) | |
tree | ec692d6516775c8362cacd0788f4374c62e9d56f /drivers/target | |
parent | 7abbe7f3e4243e28a9169ee1b8d76f10a6f5d37c (diff) |
target: Add missing DATA_SG_IO transport_cmd_get_valid_sectors check
This patch adds the missing transport_cmd_get_valid_sectors() check for
SCF_SCSI_DATA_SG_IO_CDB type payloads to ensure that a received LBA + range
does not exeed past the end of associated backend struct se_device.
This patch also fixes a bug in the failure path of transport_new_cmd_obj()
where this check can fail, so change to use a signed 'rc' and return '-EINVAL'
to signal proper transport_generic_request_failure() handling.
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d385c317a7a4..ab61c5550852 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -3891,9 +3891,7 @@ EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); | |||
3891 | static int transport_new_cmd_obj(struct se_cmd *cmd) | 3891 | static int transport_new_cmd_obj(struct se_cmd *cmd) |
3892 | { | 3892 | { |
3893 | struct se_device *dev = cmd->se_dev; | 3893 | struct se_device *dev = cmd->se_dev; |
3894 | u32 task_cdbs; | 3894 | int set_counts = 1, rc, task_cdbs; |
3895 | u32 rc; | ||
3896 | int set_counts = 1; | ||
3897 | 3895 | ||
3898 | /* | 3896 | /* |
3899 | * Setup any BIDI READ tasks and memory from | 3897 | * Setup any BIDI READ tasks and memory from |
@@ -3911,7 +3909,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd) | |||
3911 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 3909 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
3912 | cmd->scsi_sense_reason = | 3910 | cmd->scsi_sense_reason = |
3913 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3911 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3914 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3912 | return -EINVAL; |
3915 | } | 3913 | } |
3916 | atomic_inc(&cmd->t_fe_count); | 3914 | atomic_inc(&cmd->t_fe_count); |
3917 | atomic_inc(&cmd->t_se_count); | 3915 | atomic_inc(&cmd->t_se_count); |
@@ -3930,7 +3928,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd) | |||
3930 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 3928 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
3931 | cmd->scsi_sense_reason = | 3929 | cmd->scsi_sense_reason = |
3932 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3930 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3933 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3931 | return -EINVAL; |
3934 | } | 3932 | } |
3935 | 3933 | ||
3936 | if (set_counts) { | 3934 | if (set_counts) { |
@@ -4248,10 +4246,13 @@ static u32 transport_allocate_tasks( | |||
4248 | struct scatterlist *sgl, | 4246 | struct scatterlist *sgl, |
4249 | unsigned int sgl_nents) | 4247 | unsigned int sgl_nents) |
4250 | { | 4248 | { |
4251 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) | 4249 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { |
4250 | if (transport_cmd_get_valid_sectors(cmd) < 0) | ||
4251 | return -EINVAL; | ||
4252 | |||
4252 | return transport_allocate_data_tasks(cmd, lba, data_direction, | 4253 | return transport_allocate_data_tasks(cmd, lba, data_direction, |
4253 | sgl, sgl_nents); | 4254 | sgl, sgl_nents); |
4254 | else | 4255 | } else |
4255 | return transport_allocate_control_task(cmd); | 4256 | return transport_allocate_control_task(cmd); |
4256 | 4257 | ||
4257 | } | 4258 | } |