mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-01 00:36:40 +09:00
tcm_loop: Add explict read buffer memset for SCF_SCSI_CONTROL_SG_IO_CDB
commit 8cd79f2435 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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d7ded4428c
commit
eb19a95365
@@ -174,6 +174,24 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
|
||||
sgl_bidi = sdb->table.sgl;
|
||||
sgl_bidi_count = sdb->table.nents;
|
||||
}
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the core about our preallocated memory */
|
||||
ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
|
||||
|
||||
Reference in New Issue
Block a user