diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-10-24 13:35:37 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-11 09:37:01 -0800 |
commit | fef547148349098f58bcea1c6cda5be1f6f8719c (patch) | |
tree | 2521e4b3969b88c0c02902a44315ceedd78577d0 /drivers/target | |
parent | 24b791339f0e80761de402cbb13ff2ddb19b8c03 (diff) |
tcm_loop: Add explict read buffer memset for SCF_SCSI_CONTROL_SG_IO_CDB
commit 8cd79f24350826b81e16990d9e12bc878e67d385 upstream.
This patch addresses an issue with buggy userspace code sending I/O
via scsi-generic that does not explictly clear their associated read
buffers. It adds an explict memset of the first SGL entry within
tcm_loop_new_cmd_map() for SCF_SCSI_CONTROL_SG_IO_CDB payloads that
are currently guaranteed to be a single SGL by target-core code.
This issue is a side effect of the v3.1-rc1 merge to remove the
extra memcpy between certain control CDB types using a contigious
+ cleared buffer in target-core, and performing a memcpy into the
SGL list within tcm_loop.
It was originally mainfesting itself by udev + scsi_id + scsi-generic
not properly setting up the expected /dev/disk/by-id/ symlinks because
the INQUIRY payload was containing extra bogus data preventing the
proper NAA IEEE WWN from being parsed by userspace.
Cc: Christoph Hellwig <hch@lst.de>
Cc: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 70c2e7fa666..4b5421b391d 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -127,6 +127,24 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( set_host_byte(sc, DID_NO_CONNECT); return NULL; } + /* + * Because some userspace code via scsi-generic do not memset their + * associated read buffers, go ahead and do that here for type + * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently + * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB + * by target core in transport_generic_allocate_tasks() -> + * transport_generic_cmd_sequencer(). + */ + if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB && + se_cmd->data_direction == DMA_FROM_DEVICE) { + struct scatterlist *sg = scsi_sglist(sc); + unsigned char *buf = kmap(sg_page(sg)) + sg->offset; + + if (buf != NULL) { + memset(buf, 0, sg->length); + kunmap(sg_page(sg)); + } + } transport_device_setup_cmd(se_cmd); return se_cmd; |