diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-11-16 01:13:24 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-12-06 01:00:53 -0500 |
commit | fef58a6096770ed6ab49103a430cc755254a74d9 (patch) | |
tree | e59f7c7074c32e604a9b1a9f15550c0249e12546 /drivers/target | |
parent | 6fd126ffebef3897d8fca98644a9fd1cc5c7a5e3 (diff) |
target: Reject SCSI data overflow for fabrics using transport_generic_map_mem_to_cmd
This patch changes transport_generic_map_mem_to_cmd() to reject SCSI data
overflow and to send exception status with CHECK_CONDITION + TCM_INVALID_CDB_FIELD
for fabrics that are passing a pre-populated struct scatterlist (eg: tcm_loop
and iscsi-target) being mapped into se_cmd->t_data_sg and se_cmd->t_data_nents.
This addresses an OOPs where transport_allocate_data_tasks() would walk
the incorrect post OVERFLOW cmd->data_length value beyond the end of
the passed scatterlist.
Cc: Christoph Hellwig <hch@lst.de>
Cc: Andy Grover <agrover@redhat.com>
Cc: stable@kernel.org
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 8f29f472c50b..0bdb6badbf99 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -3411,6 +3411,18 @@ int transport_generic_map_mem_to_cmd( | |||
3411 | 3411 | ||
3412 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || | 3412 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || |
3413 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { | 3413 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { |
3414 | /* | ||
3415 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
3416 | * scatterlists already have been set to follow what the fabric | ||
3417 | * passes for the original expected data transfer length. | ||
3418 | */ | ||
3419 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
3420 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
3421 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
3422 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
3423 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
3424 | return -EINVAL; | ||
3425 | } | ||
3414 | 3426 | ||
3415 | cmd->t_data_sg = sgl; | 3427 | cmd->t_data_sg = sgl; |
3416 | cmd->t_data_nents = sgl_count; | 3428 | cmd->t_data_nents = sgl_count; |