diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-10-24 16:35:37 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-10-26 16:42:13 -0400 |
commit | 8cd79f24350826b81e16990d9e12bc878e67d385 (patch) | |
tree | 14421b42c8c7eeb566e5793c1dfd45d051cd74d6 /drivers/target/loopback | |
parent | c9abb9bb0b8451588509192bd53005d65c02986c (diff) |
tcm_loop: Add explict read buffer memset for SCF_SCSI_CONTROL_SG_IO_CDB
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>
Cc: stable@kernel.org
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/loopback')
-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 b15d8cbf630b..3c9c318f66ed 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -174,6 +174,24 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) | |||
174 | sgl_bidi = sdb->table.sgl; | 174 | sgl_bidi = sdb->table.sgl; |
175 | sgl_bidi_count = sdb->table.nents; | 175 | sgl_bidi_count = sdb->table.nents; |
176 | } | 176 | } |
177 | /* | ||
178 | * Because some userspace code via scsi-generic do not memset their | ||
179 | * associated read buffers, go ahead and do that here for type | ||
180 | * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently | ||
181 | * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB | ||
182 | * by target core in transport_generic_allocate_tasks() -> | ||
183 | * transport_generic_cmd_sequencer(). | ||
184 | */ | ||
185 | if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB && | ||
186 | se_cmd->data_direction == DMA_FROM_DEVICE) { | ||
187 | struct scatterlist *sg = scsi_sglist(sc); | ||
188 | unsigned char *buf = kmap(sg_page(sg)) + sg->offset; | ||
189 | |||
190 | if (buf != NULL) { | ||
191 | memset(buf, 0, sg->length); | ||
192 | kunmap(sg_page(sg)); | ||
193 | } | ||
194 | } | ||
177 | 195 | ||
178 | /* Tell the core about our preallocated memory */ | 196 | /* Tell the core about our preallocated memory */ |
179 | ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), | 197 | ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), |