Message ID | 20170504225102.8931-7-bart.vanassche@sandisk.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, 2017-05-04 at 15:50 -0700, Bart Van Assche wrote: > For VERIFY and WRITE AND VERIFY commands the size of the SCSI > Data-Out buffer can differ from the size of the data area on > the storage medium that is affected by the command. Make sure > that the Data-Out buffer size is computed correctly. Apparently > this part got dropped from my previous VERIFY / WRITE AND VERIFY > patch before I posted it due to rebasing. > > Fixes: commit 0e2eb7d12eaa ("target: Fix VERIFY and WRITE VERIFY command parsing") > Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> > Cc: Hannes Reinecke <hare@suse.com> > Cc: Christoph Hellwig <hch@lst.de> > Cc: Andy Grover <agrover@redhat.com> > Cc: David Disseldorp <ddiss@suse.de> > Cc: <stable@vger.kernel.org> > --- > drivers/target/target_core_sbc.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c > index a0ad618f1b1a..51489d96cb31 100644 > --- a/drivers/target/target_core_sbc.c > +++ b/drivers/target/target_core_sbc.c > @@ -888,9 +888,10 @@ static sense_reason_t sbc_parse_verify(struct se_cmd *cmd, int *sectors, > sense_reason_t > sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > { > + enum { INVALID_SIZE = 1 }; > struct se_device *dev = cmd->se_dev; > unsigned char *cdb = cmd->t_task_cdb; > - unsigned int size; > + unsigned int size = INVALID_SIZE; > u32 sectors = 0; > sense_reason_t ret; > > @@ -1212,7 +1213,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > return TCM_ADDRESS_OUT_OF_RANGE; > } > > - if (!(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) > + if (size == INVALID_SIZE) > size = sbc_get_size(cmd, sectors); > } > This patch has no effect. All it does for VERIFY + WRITE_AND_VERIFY is prevent sbc_get_size() from being called twice with the same parameters, because your previous patch in for-next was incorrectly only doing it for only bytchk = 1. Anyways, sbc_parse_verify() should not being doing this directly, and not for only bytchk = 1. Anyways, I've fixed both cases and will post the proper fix inline against patch #19. -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, 2017-05-07 at 15:49 -0700, Nicholas A. Bellinger wrote: > On Thu, 2017-05-04 at 15:50 -0700, Bart Van Assche wrote: > > For VERIFY and WRITE AND VERIFY commands the size of the SCSI > > Data-Out buffer can differ from the size of the data area on > > the storage medium that is affected by the command. Make sure > > that the Data-Out buffer size is computed correctly. Apparently > > this part got dropped from my previous VERIFY / WRITE AND VERIFY > > patch before I posted it due to rebasing. > > > > Fixes: commit 0e2eb7d12eaa ("target: Fix VERIFY and WRITE VERIFY command parsing") > > Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> > > Cc: Hannes Reinecke <hare@suse.com> > > Cc: Christoph Hellwig <hch@lst.de> > > Cc: Andy Grover <agrover@redhat.com> > > Cc: David Disseldorp <ddiss@suse.de> > > Cc: <stable@vger.kernel.org> > > --- > > drivers/target/target_core_sbc.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c > > index a0ad618f1b1a..51489d96cb31 100644 > > --- a/drivers/target/target_core_sbc.c > > +++ b/drivers/target/target_core_sbc.c > > @@ -888,9 +888,10 @@ static sense_reason_t sbc_parse_verify(struct se_cmd *cmd, int *sectors, > > sense_reason_t > > sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > > { > > + enum { INVALID_SIZE = 1 }; > > struct se_device *dev = cmd->se_dev; > > unsigned char *cdb = cmd->t_task_cdb; > > - unsigned int size; > > + unsigned int size = INVALID_SIZE; > > u32 sectors = 0; > > sense_reason_t ret; > > > > @@ -1212,7 +1213,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > > return TCM_ADDRESS_OUT_OF_RANGE; > > } > > > > - if (!(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) > > + if (size == INVALID_SIZE) > > size = sbc_get_size(cmd, sectors); > > } > > > > This patch has no effect. Hello Nic, That's a misinterpretation of your side. What this patch does is to ensure that 'size' remains zero if a VERIFY or WRITE AND VERIFY command is submitted with BYTCHK == 0. SBC mentions clearly that BYTCHK == 0 means that there is no Data-Out buffer, or in other words, that the size of the Data-Out buffer is zero. From the sg_verify man page: When --ndo=NDO is not given then the verify starts at the logical block address given by the --lba=LBA option and continues for --count=COUNT blocks. In other words, sg_verify is able to submit a VERIFY command without Data-Out buffer (NDO is the size of the Data-Out buffer in bytes). > Anyways, I've fixed both cases and will post the proper fix inline > against patch #19. Do you perhaps mean patch "target: Fix sbc_parse_verify bytchk = 0 handling"? (https://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git/commit/?h=for-next&id=d7d40280f868463d01a82186fd61cdc0e590381f) If you want to know my opinion about that patch: it doesn't fix anything but breaks the sbc_parse_verify() function and definitely doesn't make the behavior of VERIFY nor WRITE AND VERIFY more compliant with the SCSI specs. Bart.-- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2017-05-08 at 18:07 +0000, Bart Van Assche wrote: > On Sun, 2017-05-07 at 15:49 -0700, Nicholas A. Bellinger wrote: > > On Thu, 2017-05-04 at 15:50 -0700, Bart Van Assche wrote: > > > For VERIFY and WRITE AND VERIFY commands the size of the SCSI > > > Data-Out buffer can differ from the size of the data area on > > > the storage medium that is affected by the command. Make sure > > > that the Data-Out buffer size is computed correctly. Apparently > > > this part got dropped from my previous VERIFY / WRITE AND VERIFY > > > patch before I posted it due to rebasing. > > > > > > Fixes: commit 0e2eb7d12eaa ("target: Fix VERIFY and WRITE VERIFY command parsing") > > > Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> > > > Cc: Hannes Reinecke <hare@suse.com> > > > Cc: Christoph Hellwig <hch@lst.de> > > > Cc: Andy Grover <agrover@redhat.com> > > > Cc: David Disseldorp <ddiss@suse.de> > > > Cc: <stable@vger.kernel.org> > > > --- > > > drivers/target/target_core_sbc.c | 5 +++-- > > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c > > > index a0ad618f1b1a..51489d96cb31 100644 > > > --- a/drivers/target/target_core_sbc.c > > > +++ b/drivers/target/target_core_sbc.c > > > @@ -888,9 +888,10 @@ static sense_reason_t sbc_parse_verify(struct se_cmd *cmd, int *sectors, > > > sense_reason_t > > > sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > > > { > > > + enum { INVALID_SIZE = 1 }; > > > struct se_device *dev = cmd->se_dev; > > > unsigned char *cdb = cmd->t_task_cdb; > > > - unsigned int size; > > > + unsigned int size = INVALID_SIZE; > > > u32 sectors = 0; > > > sense_reason_t ret; > > > > > > @@ -1212,7 +1213,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) > > > return TCM_ADDRESS_OUT_OF_RANGE; > > > } > > > > > > - if (!(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) > > > + if (size == INVALID_SIZE) > > > size = sbc_get_size(cmd, sectors); > > > } > > > > > > > This patch has no effect. > > Hello Nic, > > That's a misinterpretation of your side. What this patch does is to ensure > that 'size' remains zero if a VERIFY or WRITE AND VERIFY command is submitted > with BYTCHK == 0. SBC mentions clearly that BYTCHK == 0 means that there is > no Data-Out buffer, or in other words, that the size of the Data-Out buffer > is zero. > > From the sg_verify man page: > > When --ndo=NDO is not given then the verify starts at the logical block > address given by the --lba=LBA option and continues for --count=COUNT > blocks. > > In other words, sg_verify is able to submit a VERIFY command without Data-Out > buffer (NDO is the size of the Data-Out buffer in bytes). > That's fine the spec says no data is associated with bytchk = 0. The point is the 'size' value in sbc_parse_cdb() is what's extracted from the received CDB, and compared against extended data transfer length (cmd->data_length) in target_cmd_size_check() to determine overflow or underflow. Attempting to make 'size' in sbc_parse_cdb() enforce what the spec says, instead of what it actually is in the received CDB is completely wrong. No other CDB does this, and *VERIFY* is no exception. If you're worried about non zero transfer length with bytchk = 0 getting processed, go ahead and return TCM_INVALID_CDB_FIELD from sbc_parse_verify() when this happens, like every other sanity check does. Of course, that's exactly the test case libiscsi does during test_writeverify16_residuals, send bythck = 0 with overflow and underflow with a non zero transfer length. > > Anyways, I've fixed both cases and will post the proper fix inline > > against patch #19. > > Do you perhaps mean patch "target: Fix sbc_parse_verify bytchk = 0 handling"? > (https://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git/commit/?h=for-next&id=d7d40280f868463d01a82186fd61cdc0e590381f) > > If you want to know my opinion about that patch: it doesn't fix anything but > breaks the sbc_parse_verify() function and definitely doesn't make the > behavior of VERIFY nor WRITE AND VERIFY more compliant with the SCSI specs. You are incorrect. It addresses the regression your code introduced that broke existing behavior for WRITE_VERIFY_*, when sbc_parse_verify() dropped SCF_SCSI_DATA_CDB for bytchk = 0 that allowed overflow to trigger an NULL pointer dereference. Perhaps you should verify existing code before your sbc_parse_verify() changes to see what I'm talking about. -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 2017-05-09 at 21:28 -0700, Nicholas A. Bellinger wrote: > Attempting to make 'size' in sbc_parse_cdb() enforce what the spec says, > instead of what it actually is in the received CDB is completely wrong. Please look again at e.g. the sg_verify source code. If it sets BYTCHK to zero it doesn't submit a Data-Out buffer. The only initiator that submits a Data-Out buffer and sets BYTCHK to zero is libiscsi when testing overflow behavior. Bart.-- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a0ad618f1b1a..51489d96cb31 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -888,9 +888,10 @@ static sense_reason_t sbc_parse_verify(struct se_cmd *cmd, int *sectors, sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) { + enum { INVALID_SIZE = 1 }; struct se_device *dev = cmd->se_dev; unsigned char *cdb = cmd->t_task_cdb; - unsigned int size; + unsigned int size = INVALID_SIZE; u32 sectors = 0; sense_reason_t ret; @@ -1212,7 +1213,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) return TCM_ADDRESS_OUT_OF_RANGE; } - if (!(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) + if (size == INVALID_SIZE) size = sbc_get_size(cmd, sectors); }
For VERIFY and WRITE AND VERIFY commands the size of the SCSI Data-Out buffer can differ from the size of the data area on the storage medium that is affected by the command. Make sure that the Data-Out buffer size is computed correctly. Apparently this part got dropped from my previous VERIFY / WRITE AND VERIFY patch before I posted it due to rebasing. Fixes: commit 0e2eb7d12eaa ("target: Fix VERIFY and WRITE VERIFY command parsing") Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Andy Grover <agrover@redhat.com> Cc: David Disseldorp <ddiss@suse.de> Cc: <stable@vger.kernel.org> --- drivers/target/target_core_sbc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)