diff mbox series

sd: Protect against submitting READ(6) or WRITE(6) with 256 logical blocks

Message ID 20190123191237.119996-1-bvanassche@acm.org (mailing list archive)
State Mainlined
Commit db5db4b91cabcf57f3efd98d92d24ab875cde8ae
Headers show
Series sd: Protect against submitting READ(6) or WRITE(6) with 256 logical blocks | expand

Commit Message

Bart Van Assche Jan. 23, 2019, 7:12 p.m. UTC
Since the READ(6) and WRITE(6) commands interpret a zero in the transfer
length field in the CDB as 256 logical blocks, avoid submitting such
commands.

Cc: Douglas Gilbert <dgilbert@interlog.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Reported-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/sd.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Douglas Gilbert Jan. 23, 2019, 7:31 p.m. UTC | #1
On 2019-01-23 2:12 p.m., Bart Van Assche wrote:
> Since the READ(6) and WRITE(6) commands interpret a zero in the transfer
> length field in the CDB as 256 logical blocks, avoid submitting such
> commands.
> 
> Cc: Douglas Gilbert <dgilbert@interlog.com>
> Cc: Hannes Reinecke <hare@suse.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Reported-by: Douglas Gilbert <dgilbert@interlog.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>

Reviewed-by: Douglas Gilbert <dgilbert@interlog.com>

> ---
>   drivers/scsi/sd.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 4e69f182a1e5..b0eb83526c54 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -1129,6 +1129,10 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
>   				      sector_t lba, unsigned int nr_blocks,
>   				      unsigned char flags)
>   {
> +	/* Avoid that 0 blocks gets translated into 256 blocks. */
> +	if (WARN_ON_ONCE(nr_blocks == 0))
> +		return BLK_STS_IOERR;
> +
>   	if (unlikely(flags & 0x8)) {
>   		/*
>   		 * This happens only if this drive failed 10byte rw
>
Hannes Reinecke Jan. 24, 2019, 12:29 p.m. UTC | #2
On 1/23/19 8:12 PM, Bart Van Assche wrote:
> Since the READ(6) and WRITE(6) commands interpret a zero in the transfer
> length field in the CDB as 256 logical blocks, avoid submitting such
> commands.
> 
> Cc: Douglas Gilbert <dgilbert@interlog.com>
> Cc: Hannes Reinecke <hare@suse.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Reported-by: Douglas Gilbert <dgilbert@interlog.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>   drivers/scsi/sd.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 4e69f182a1e5..b0eb83526c54 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -1129,6 +1129,10 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
>   				      sector_t lba, unsigned int nr_blocks,
>   				      unsigned char flags)
>   {
> +	/* Avoid that 0 blocks gets translated into 256 blocks. */
> +	if (WARN_ON_ONCE(nr_blocks == 0))
> +		return BLK_STS_IOERR;
> +
>   	if (unlikely(flags & 0x8)) {
>   		/*
>   		 * This happens only if this drive failed 10byte rw
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
Martin K. Petersen Jan. 29, 2019, 5:51 a.m. UTC | #3
Bart,

> Since the READ(6) and WRITE(6) commands interpret a zero in the transfer
> length field in the CDB as 256 logical blocks, avoid submitting such
> commands.

Applied to 5.1/scsi-queue, thanks.
Christoph Hellwig Jan. 29, 2019, 8:40 a.m. UTC | #4
On Wed, Jan 23, 2019 at 11:12:37AM -0800, Bart Van Assche wrote:
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 4e69f182a1e5..b0eb83526c54 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -1129,6 +1129,10 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
>  				      sector_t lba, unsigned int nr_blocks,
>  				      unsigned char flags)
>  {
> +	/* Avoid that 0 blocks gets translated into 256 blocks. */
> +	if (WARN_ON_ONCE(nr_blocks == 0))
> +		return BLK_STS_IOERR;
> +

While the WARN_ON here looks helpful shouldn't we instead ensure that
sd_setup_rw6_cmnd never gets called with a 0 argument instead of bailing
out like this?
Bart Van Assche Jan. 29, 2019, 2:54 p.m. UTC | #5
On 1/29/19 12:40 AM, Christoph Hellwig wrote:
> On Wed, Jan 23, 2019 at 11:12:37AM -0800, Bart Van Assche wrote:
>> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
>> index 4e69f182a1e5..b0eb83526c54 100644
>> --- a/drivers/scsi/sd.c
>> +++ b/drivers/scsi/sd.c
>> @@ -1129,6 +1129,10 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
>>   				      sector_t lba, unsigned int nr_blocks,
>>   				      unsigned char flags)
>>   {
>> +	/* Avoid that 0 blocks gets translated into 256 blocks. */
>> +	if (WARN_ON_ONCE(nr_blocks == 0))
>> +		return BLK_STS_IOERR;
>> +
> 
> While the WARN_ON here looks helpful shouldn't we instead ensure that
> sd_setup_rw6_cmnd never gets called with a 0 argument instead of bailing
> out like this?

Hi Christoph,

Before I posted this patch I searched for code that submits read or 
write requests with length 0 but I haven't found any. do_iter_read() and 
do_iter_write() in fs/read_write.c do not submit any block layer 
requests if tot_len == 0. Are you perhaps aware of kernel code that can 
submit zero-length read or write requests?

Thanks,

Bart.
Martin K. Petersen Feb. 1, 2019, 3:30 a.m. UTC | #6
Bart,

>> While the WARN_ON here looks helpful shouldn't we instead ensure that
>> sd_setup_rw6_cmnd never gets called with a 0 argument instead of bailing
>> out like this?
>
> Before I posted this patch I searched for code that submits read or
> write requests with length 0 but I haven't found any. do_iter_read()
> and do_iter_write() in fs/read_write.c do not submit any block layer
> requests if tot_len == 0. Are you perhaps aware of kernel code that
> can submit zero-length read or write requests?

At some level I would have liked the sanity check in the top rw prep
command. However, given that a zero transfer length is mostly a
hypothetical scenario I tend to concur with sticking the check in rw6
outside of the hot path.
diff mbox series

Patch

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 4e69f182a1e5..b0eb83526c54 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1129,6 +1129,10 @@  static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
 				      sector_t lba, unsigned int nr_blocks,
 				      unsigned char flags)
 {
+	/* Avoid that 0 blocks gets translated into 256 blocks. */
+	if (WARN_ON_ONCE(nr_blocks == 0))
+		return BLK_STS_IOERR;
+
 	if (unlikely(flags & 0x8)) {
 		/*
 		 * This happens only if this drive failed 10byte rw