All of lore.kernel.org
 help / color / mirror / Atom feed
* Bugs in scsi_vpd_inquiry()
@ 2009-08-10 14:41 Alan Stern
  2009-08-10 14:58 ` Matthew Wilcox
  2009-08-11  7:07 ` Boaz Harrosh
  0 siblings, 2 replies; 24+ messages in thread
From: Alan Stern @ 2009-08-10 14:41 UTC (permalink / raw)
  To: Martin K. Petersen, Matthew Wilcox; +Cc: SCSI development list

Martin and Matthew:

Since you guys added scsi_vpd_inquiry() and scsi_get_vpd_page() plus
sd_read_block_limits() and sd_read_block_characteristics(), I'm
directing these questions to you.

Is there some reason for not accounting for the 4 header bytes in the 
allocation length value stored in the CDB?  Or is this simply a bug?

Were you aware that SCSI-2 defines the allocation length to be a single 
byte?  cmd[3] is specified as "Reserved" in the spec.  Hence the value 
of "len" should be capped at 255 if sdev->scsi_level <= SCSI_2, right?

Why does scsi_get_vpd_page() retrieve page 0 first, rather than 
directly asking for the page in question?  Is this some sort of 
play-it-safe approach, to avoid sending devices commands they may not 
support?

Have you considered that plenty of low-budget USB mass-storage devices
don't implement VPD properly?  I've got a flash drive right here which
totally ignores the "page" byte in the INQUIRY command; it always
responds with the normal INQUIRY data.  Thus expecting the response
data always to be accurate may not be a good idea.  I'm considering
adding a "restrict_to_MS_usb" flag to the host template, to indicate
that commands shouldn't be sent unless some version of Windows uses
them when talking to USB devices -- do you think that could work?

Finally, what's your opinion on the proposed patch below?

Alan Stern



Index: usb-2.6/drivers/scsi/scsi.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi.c
+++ usb-2.6/drivers/scsi/scsi.c
@@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
  * @sdev: The device to ask
  * @buffer: Where to put the result
  * @page: Which Vital Product Data to return
- * @len: The length of the buffer
+ * @len: The length of the data (= buffer length - 4)
  *
  * This is an internal helper function.  You probably want to use
  * scsi_get_vpd_page instead.
@@ -982,6 +982,12 @@ static int scsi_vpd_inquiry(struct scsi_
 	int result;
 	unsigned char cmd[16];
 
+	len += 4;		/* Include room for the header bytes */
+
+	/* SCSI-2 and earlier allow only 1 byte for the allocation length */
+	if (sdev->scsi_level <= SCSI_2)
+		len = min(len, 255u);
+
 	cmd[0] = INQUIRY;
 	cmd[1] = 1;		/* EVPD */
 	cmd[2] = page;
@@ -994,7 +1000,7 @@ static int scsi_vpd_inquiry(struct scsi_
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL);
 	if (result)
 		return result;
 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 14:41 Bugs in scsi_vpd_inquiry() Alan Stern
@ 2009-08-10 14:58 ` Matthew Wilcox
  2009-08-10 15:32   ` Alan Stern
  2009-08-11  7:07 ` Boaz Harrosh
  1 sibling, 1 reply; 24+ messages in thread
From: Matthew Wilcox @ 2009-08-10 14:58 UTC (permalink / raw)
  To: Alan Stern; +Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list

On Mon, Aug 10, 2009 at 10:41:42AM -0400, Alan Stern wrote:
> Martin and Matthew:
> 
> Since you guys added scsi_vpd_inquiry() and scsi_get_vpd_page() plus
> sd_read_block_limits() and sd_read_block_characteristics(), I'm
> directing these questions to you.
> 
> Is there some reason for not accounting for the 4 header bytes in the 
> allocation length value stored in the CDB?  Or is this simply a bug?

Um, we do.

unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
        unsigned char *buf = kmalloc(259, GFP_KERNEL);
        result = scsi_vpd_inquiry(sdev, buf, 0, 255);
        for (i = 0; i < buf[3]; i++)
                if (buf[i + 4] == page)
                        goto found;
        buf = kmalloc(len + 4, GFP_KERNEL);
        result = scsi_vpd_inquiry(sdev, buf, page, len);

Now ... we do seem to be passing the len instead of len + 4 to the
device as the buffer size, so there does appear to be a minor bug here,
but it's not as horrific as you make it out to be.

> Were you aware that SCSI-2 defines the allocation length to be a single 
> byte?  cmd[3] is specified as "Reserved" in the spec.  Hence the value 
> of "len" should be capped at 255 if sdev->scsi_level <= SCSI_2, right?

and 'Reserved' in SCSI-2 means:

"A reserved bit, field, or byte shall be set to zero, or in accordance
with a future extension to this standard." (7.1.1)

> Why does scsi_get_vpd_page() retrieve page 0 first, rather than 
> directly asking for the page in question?  Is this some sort of 
> play-it-safe approach, to avoid sending devices commands they may not 
> support?

I think we had an example of a device which crashed when asked for pages
that it didn't support.

> Have you considered that plenty of low-budget USB mass-storage devices
> don't implement VPD properly?  I've got a flash drive right here which

I've noticed you whining about it, yes.

> totally ignores the "page" byte in the INQUIRY command; it always
> responds with the normal INQUIRY data.  Thus expecting the response

I don't think you mean the 'page' byte.  I think you mean the 'EVPD'
bit.

> data always to be accurate may not be a good idea.  I'm considering
> adding a "restrict_to_MS_usb" flag to the host template, to indicate
> that commands shouldn't be sent unless some version of Windows uses
> them when talking to USB devices -- do you think that could work?

Not really my area of expertise.

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 14:58 ` Matthew Wilcox
@ 2009-08-10 15:32   ` Alan Stern
  2009-08-10 17:08     ` Martin K. Petersen
  2009-08-11 16:04     ` Matthew Wilcox
  0 siblings, 2 replies; 24+ messages in thread
From: Alan Stern @ 2009-08-10 15:32 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list

On Mon, 10 Aug 2009, Matthew Wilcox wrote:

> On Mon, Aug 10, 2009 at 10:41:42AM -0400, Alan Stern wrote:
> > Martin and Matthew:
> > 
> > Since you guys added scsi_vpd_inquiry() and scsi_get_vpd_page() plus
> > sd_read_block_limits() and sd_read_block_characteristics(), I'm
> > directing these questions to you.
> > 
> > Is there some reason for not accounting for the 4 header bytes in the 
> > allocation length value stored in the CDB?  Or is this simply a bug?
> 
> Um, we do.
> 
> unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
>         unsigned char *buf = kmalloc(259, GFP_KERNEL);
>         result = scsi_vpd_inquiry(sdev, buf, 0, 255);
>         for (i = 0; i < buf[3]; i++)
>                 if (buf[i + 4] == page)
>                         goto found;
>         buf = kmalloc(len + 4, GFP_KERNEL);
>         result = scsi_vpd_inquiry(sdev, buf, page, len);

I'm not referring to this routine; I'm talking about the code in 
scsi_vpd_inquiry() where the CDB is set.

> Now ... we do seem to be passing the len instead of len + 4 to the
> device as the buffer size,

Yes, that's what I mean.

> so there does appear to be a minor bug here,
> but it's not as horrific as you make it out to be.

I didn't make it out to be horrific; I said that it's "simply a bug".  
And you just agreed with me.  (Well, you called it a "minor" bug; I'll 
go along with that.)


> > Were you aware that SCSI-2 defines the allocation length to be a single 
> > byte?  cmd[3] is specified as "Reserved" in the spec.  Hence the value 
> > of "len" should be capped at 255 if sdev->scsi_level <= SCSI_2, right?
> 
> and 'Reserved' in SCSI-2 means:
> 
> "A reserved bit, field, or byte shall be set to zero, or in accordance
> with a future extension to this standard." (7.1.1)

Sure.  But what reason could there possibly be for making a field
non-zero when you know that the device won't be able to interpret the
value correctly?  The fact that sdev->scsi_level == SCSI_2 means
the device follows _this_ version of the standard, not a future 
extension.  Or am I missing something?


> > Have you considered that plenty of low-budget USB mass-storage devices
> > don't implement VPD properly?  I've got a flash drive right here which
> 
> I've noticed you whining about it, yes.

Have I mentioned it before?  I don't recall doing so...  Maybe my 
memory is going.

(And there's no reason to be rude.  I'm trying to hold a civil
discussion.)

> > totally ignores the "page" byte in the INQUIRY command; it always
> > responds with the normal INQUIRY data.  Thus expecting the response
> 
> I don't think you mean the 'page' byte.  I think you mean the 'EVPD'
> bit.

That's right.  Sorry about the mental slip-up.

> > data always to be accurate may not be a good idea.  I'm considering
> > adding a "restrict_to_MS_usb" flag to the host template, to indicate
> > that commands shouldn't be sent unless some version of Windows uses
> > them when talking to USB devices -- do you think that could work?
> 
> Not really my area of expertise.

Okay.  Maybe Martin has some thoughts on it.

You didn't comment on the proposed patch.  Any objections to it?

Alan Stern


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 15:32   ` Alan Stern
@ 2009-08-10 17:08     ` Martin K. Petersen
  2009-08-10 20:13       ` Alan Stern
  2009-08-10 21:53       ` Douglas Gilbert
  2009-08-11 16:04     ` Matthew Wilcox
  1 sibling, 2 replies; 24+ messages in thread
From: Martin K. Petersen @ 2009-08-10 17:08 UTC (permalink / raw)
  To: Alan Stern
  Cc: Matthew Wilcox, Martin K. Petersen, Matthew Wilcox,
	SCSI development list

>>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:

Alan,

>> > data always to be accurate may not be a good idea.  I'm considering
>> > adding a "restrict_to_MS_usb" flag to the host template, to
>> > indicate that commands shouldn't be sent unless some version of
>> > Windows uses them when talking to USB devices -- do you think that
>> > could work?
>> 
>> Not really my area of expertise.

Alan> Okay.  Maybe Martin has some thoughts on it.

First of all we're not going to send EVPD=1 out to devices reporting
SCSI_SPC_2 or lower anymore, making some of this discussion moot in the
short term.

But as I have alluded to in the past we do have a conflict brewing
because the switch to drives with 4KB physical blocks will mean USB
bridges will have to get smarter.  And that in turn will mean adhering
(*gasp*) to the standard instead of firmware writers flipping bits until
Windows stops crashing.  Windows 7 does in fact query drives about
alignment, block sizes, etc.  But I'm not sure how true that is for the
Windows USB storage stack.

Originally I was in favor of just considering any USB device suspect and
only send it a limited command set.  But the 4KB switch means that it is
imperative that we get the alignment reported correctly.  Performance is
totally and absolutely going to tank without it.  Enough that users will
complain loudly.

Consequently, I'm no longer a fan of the reduced command set approach.
Because in 12 months that MS command set *will* include stuff that
causes existing USB devices to crash, catch fire, or eat your breakfast.

And then we're back to finding heuristics for USB device brain damage.
Blindly clamping the SCSI rev. in scsiglue.c will have to be replaced
with something smarter.  And I really think that's what needs to be
fixed.

Please note that I'm not trying to weasel out of changing stuff in SCSI.
But it's USB devices that deviate wildly from the spec, so I think we
should keep as much of the workaround stuff in the USB stack as
possible.  And the current SCSI rev. mechanism is a reasonable way to
limit what we send out in sd.c.

So I'd prefer an approach where the USB stack sets the SCSI level
according to how much it trusts the attached device.

Is there a USB rev. or something else you can key off of and combine
with the device-reported SCSI rev. to come up with a better heuristic?
Something which doesn't depend on being SCSIly correct.

Do we have any way of identifying the devices that caused the SCSI
rev. to be clamped for USB in the first place?  Any way of collecting
that data over a couple of kernel release cycles?

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 17:08     ` Martin K. Petersen
@ 2009-08-10 20:13       ` Alan Stern
  2009-08-10 20:49         ` Martin K. Petersen
  2009-08-10 21:53       ` Douglas Gilbert
  1 sibling, 1 reply; 24+ messages in thread
From: Alan Stern @ 2009-08-10 20:13 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: Matthew Wilcox, Matthew Wilcox, SCSI development list

On Mon, 10 Aug 2009, Martin K. Petersen wrote:

> >>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:
> 
> Alan,
> 
> >> > data always to be accurate may not be a good idea.  I'm considering
> >> > adding a "restrict_to_MS_usb" flag to the host template, to
> >> > indicate that commands shouldn't be sent unless some version of
> >> > Windows uses them when talking to USB devices -- do you think that
> >> > could work?
> >> 
> >> Not really my area of expertise.
> 
> Alan> Okay.  Maybe Martin has some thoughts on it.
> 
> First of all we're not going to send EVPD=1 out to devices reporting
> SCSI_SPC_2 or lower anymore, making some of this discussion moot in the
> short term.

Ah.  Has this change been posted anywhere yet?

> But as I have alluded to in the past we do have a conflict brewing
> because the switch to drives with 4KB physical blocks will mean USB
> bridges will have to get smarter.

If only all the existing bridges could be made smarter too!  :-)

>  And that in turn will mean adhering
> (*gasp*) to the standard instead of firmware writers flipping bits until
> Windows stops crashing.  Windows 7 does in fact query drives about
> alignment, block sizes, etc.  But I'm not sure how true that is for the
> Windows USB storage stack.

Does Vista also do this querying?  I've got access to a machine running 
Vista, so I can test the USB storage stack behavior.  But I don't have 
access to any machines with Windows 7.

> Originally I was in favor of just considering any USB device suspect and
> only send it a limited command set.  But the 4KB switch means that it is
> imperative that we get the alignment reported correctly.  Performance is
> totally and absolutely going to tank without it.  Enough that users will
> complain loudly.
> 
> Consequently, I'm no longer a fan of the reduced command set approach.
> Because in 12 months that MS command set *will* include stuff that
> causes existing USB devices to crash, catch fire, or eat your breakfast.

How will Windows 7 deal with all those old buggy USB devices?  (You 
probably don't have any idea...)

> And then we're back to finding heuristics for USB device brain damage.
> Blindly clamping the SCSI rev. in scsiglue.c will have to be replaced
> with something smarter.  And I really think that's what needs to be
> fixed.

I generally agree.  But finding a solution won't be easy.

> Please note that I'm not trying to weasel out of changing stuff in SCSI.
> But it's USB devices that deviate wildly from the spec, so I think we
> should keep as much of the workaround stuff in the USB stack as
> possible.  And the current SCSI rev. mechanism is a reasonable way to
> limit what we send out in sd.c.
> 
> So I'd prefer an approach where the USB stack sets the SCSI level
> according to how much it trusts the attached device.
> 
> Is there a USB rev. or something else you can key off of and combine
> with the device-reported SCSI rev. to come up with a better heuristic?
> Something which doesn't depend on being SCSIly correct.

No, there isn't.  There are USB device IDs, but they are assigned more 
or less randomly by the manufacturers -- they don't form a nicely 
increasing sequence of revision numbers.

Even worse, the device-reported SCSI rev. is completely independent of
the ID for the bridge chip, which is where the failures seem to occur.  
(Although it's hard to be certain which component is failing.)

> Do we have any way of identifying the devices that caused the SCSI
> rev. to be clamped for USB in the first place?  Any way of collecting
> that data over a couple of kernel release cycles?

Some of them are listed in the email archives.  Searching through some
old records I came across this example:

	http://marc.info/?l=linux-scsi&m=110895748728466&w=2

Unfortunately this thread doesn't contain the original bug report with
the USB device ID; I think the files were put up on a web server that 
doesn't exist any more.

I'm not keen on the idea of collecting more failure data by changing
the driver so as to cause failures!

Alan Stern


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 20:13       ` Alan Stern
@ 2009-08-10 20:49         ` Martin K. Petersen
  2009-08-10 21:14           ` Alan Stern
  0 siblings, 1 reply; 24+ messages in thread
From: Martin K. Petersen @ 2009-08-10 20:49 UTC (permalink / raw)
  To: Alan Stern
  Cc: Martin K. Petersen, Matthew Wilcox, Matthew Wilcox,
	SCSI development list

>>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:

>> First of all we're not going to send EVPD=1 out to devices reporting
>> SCSI_SPC_2 or lower anymore, making some of this discussion moot in
>> the short term.

Alan> Ah.  Has this change been posted anywhere yet?

ffd4bc2a984fab40ed969163efdff321490e8032


Alan> Does Vista also do this querying?  I've got access to a machine
Alan> running Vista, so I can test the USB storage stack behavior.

Dunno.


Alan> How will Windows 7 deal with all those old buggy USB devices?
Alan> (You probably don't have any idea...)

Nope :)


Alan> No, there isn't.  There are USB device IDs, but they are assigned
Alan> more or less randomly by the manufacturers -- they don't form a
Alan> nicely increasing sequence of revision numbers.

But let's assume for a second that USB drives with 4KB physical blocks
will be USB 3.0.  I think that's a likely scenario.  Couldn't we do
something like?

   /* Dumb down SCSI level for USB 1.1 and 2.0 devices */
   if (le16_to_cpu(udev->descriptor.bcdUSB) <= 0x0200 
       && sdev->scsi_level > SCSI_2)
          sdev->sdev_target->scsi_level = sdev->scsi_level = SCSI_2;

I'm sure that won't catch all devices.  But it would at least be a step
in the right direction.  And if that breaks we can revisit.


Alan> Even worse, the device-reported SCSI rev. is completely
Alan> independent of the ID for the bridge chip, which is where the
Alan> failures seem to occur.  (Although it's hard to be certain which
Alan> component is failing.)

If the bridge doesn't provide the SCSI rev. where does it come from?  Or
are you saying there's a USB "target" chip and then a USB-SATA bridge
chip behind it?


Alan> I'm not keen on the idea of collecting more failure data by
Alan> changing the driver so as to cause failures!

I wasn't thinking a hard fail.  More like a:

  printk(KERN_ERR "Please mail this info to linux-scsi@vger...");

and have that sit in Fedora/Ubuntu for 6 months.

But if there's nothing we can key off of then there's no point.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 20:49         ` Martin K. Petersen
@ 2009-08-10 21:14           ` Alan Stern
  2009-08-10 22:47             ` Martin K. Petersen
  0 siblings, 1 reply; 24+ messages in thread
From: Alan Stern @ 2009-08-10 21:14 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: Matthew Wilcox, SCSI development list

On Mon, 10 Aug 2009, Martin K. Petersen wrote:

> >>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:
> 
> >> First of all we're not going to send EVPD=1 out to devices reporting
> >> SCSI_SPC_2 or lower anymore, making some of this discussion moot in
> >> the short term.
> 
> Alan> Ah.  Has this change been posted anywhere yet?
> 
> ffd4bc2a984fab40ed969163efdff321490e8032

Looks good, thanks.

> But let's assume for a second that USB drives with 4KB physical blocks
> will be USB 3.0.  I think that's a likely scenario.  Couldn't we do
> something like?
> 
>    /* Dumb down SCSI level for USB 1.1 and 2.0 devices */
>    if (le16_to_cpu(udev->descriptor.bcdUSB) <= 0x0200 
>        && sdev->scsi_level > SCSI_2)
>           sdev->sdev_target->scsi_level = sdev->scsi_level = SCSI_2;
> 
> I'm sure that won't catch all devices.  But it would at least be a step
> in the right direction.  And if that breaks we can revisit.

That's a good idea.  At least it won't break any existing devices, 
although some new ones may fail.


> Alan> Even worse, the device-reported SCSI rev. is completely
> Alan> independent of the ID for the bridge chip, which is where the
> Alan> failures seem to occur.  (Although it's hard to be certain which
> Alan> component is failing.)
> 
> If the bridge doesn't provide the SCSI rev. where does it come from?  Or
> are you saying there's a USB "target" chip and then a USB-SATA bridge
> chip behind it?

There's the bridge chip and the drive itself.  The drive provides the 
INQUIRY data and the chip provides the USB identifiers.

The same bridge chip can be used with lots of different drives.  In
fact, you can buy a USB-(S)ATA converter and plug it into whatever
drives you have lying around.

> Alan> I'm not keen on the idea of collecting more failure data by
> Alan> changing the driver so as to cause failures!
> 
> I wasn't thinking a hard fail.  More like a:
> 
>   printk(KERN_ERR "Please mail this info to linux-scsi@vger...");
> 
> and have that sit in Fedora/Ubuntu for 6 months.
> 
> But if there's nothing we can key off of then there's no point.

About the only thing to key off of is failure of the device when we 
send it a REPORT LUNS command.  :-(

Alan Stern


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 17:08     ` Martin K. Petersen
  2009-08-10 20:13       ` Alan Stern
@ 2009-08-10 21:53       ` Douglas Gilbert
  2009-08-10 22:52         ` Martin K. Petersen
  1 sibling, 1 reply; 24+ messages in thread
From: Douglas Gilbert @ 2009-08-10 21:53 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: Alan Stern, Matthew Wilcox, Matthew Wilcox, SCSI development list

Martin K. Petersen wrote:
>>>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:
> 
> Alan,
> 
>>>> data always to be accurate may not be a good idea.  I'm considering
>>>> adding a "restrict_to_MS_usb" flag to the host template, to
>>>> indicate that commands shouldn't be sent unless some version of
>>>> Windows uses them when talking to USB devices -- do you think that
>>>> could work?
>>> Not really my area of expertise.
> 
> Alan> Okay.  Maybe Martin has some thoughts on it.
> 
> First of all we're not going to send EVPD=1 out to devices reporting
> SCSI_SPC_2 or lower anymore, making some of this discussion moot in the
> short term.
> 
> But as I have alluded to in the past we do have a conflict brewing
> because the switch to drives with 4KB physical blocks will mean USB
> bridges will have to get smarter.  And that in turn will mean adhering
> (*gasp*) to the standard instead of firmware writers flipping bits until
> Windows stops crashing.  Windows 7 does in fact query drives about
> alignment, block sizes, etc.  But I'm not sure how true that is for the
> Windows USB storage stack.

It would be interesting to know if Windows 7 is pushing
UAS (USB attached SCSI) [latest draft at www.t10.org is
uas-r02.pdf].

"USB Attached SCSI is a new generation of USB Transport
  Standards. This standard supports the following
  features in support of USB-20 and future USB
  specifications:
     a)  does not interfere with the USB Mass Storage Class
         (MSC) bulk-only transport;
     b)  mechanism to send commands associated with any T10
         standard to a USB device;
     c)  support for queuing in the protocol;
     d)  support for autosense;
     e)  compliance with SCSI Architecture Model - 4 (SAM-4)
         or later; and
     f)  other capabilities."

It is at the letter ballot stage at t10.


Doug Gilbert



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 21:14           ` Alan Stern
@ 2009-08-10 22:47             ` Martin K. Petersen
  2009-08-11 14:35               ` Alan Stern
  0 siblings, 1 reply; 24+ messages in thread
From: Martin K. Petersen @ 2009-08-10 22:47 UTC (permalink / raw)
  To: Alan Stern; +Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list

>>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:

Alan,

>> If the bridge doesn't provide the SCSI rev. where does it come from?
>> Or are you saying there's a USB "target" chip and then a USB-SATA
>> bridge chip behind it?

Alan> There's the bridge chip and the drive itself.  The drive provides
Alan> the INQUIRY data and the chip provides the USB identifiers.

But the drive is ATA.  It must be the bridge that translates whatever
the drive reports in IDENTIFY DEVICE into something that makes sense in
the SPC/SBC universe.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 21:53       ` Douglas Gilbert
@ 2009-08-10 22:52         ` Martin K. Petersen
  0 siblings, 0 replies; 24+ messages in thread
From: Martin K. Petersen @ 2009-08-10 22:52 UTC (permalink / raw)
  To: dgilbert
  Cc: Martin K. Petersen, Alan Stern, Matthew Wilcox, Matthew Wilcox,
	SCSI development list

>>>>> "Doug" == Douglas Gilbert <dgilbert@interlog.com> writes:

Doug> It would be interesting to know if Windows 7 is pushing UAS (USB
Doug> attached SCSI) [latest draft at www.t10.org is uas-r02.pdf].

I'll see what I can dig up...

In any case UAS is a transport class.  Sure, it would provide us with
another "can't-be-completely-brain-dead" heuristic.  But we're still at
the firmware writer's whim when it comes to SPC/SBC-level commands.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 14:41 Bugs in scsi_vpd_inquiry() Alan Stern
  2009-08-10 14:58 ` Matthew Wilcox
@ 2009-08-11  7:07 ` Boaz Harrosh
  2009-08-11 14:53   ` Alan Stern
  1 sibling, 1 reply; 24+ messages in thread
From: Boaz Harrosh @ 2009-08-11  7:07 UTC (permalink / raw)
  To: Alan Stern
  Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list,
	James Bottomley

On 08/10/2009 05:41 PM, Alan Stern wrote:
> Martin and Matthew:
> 
> Since you guys added scsi_vpd_inquiry() and scsi_get_vpd_page() plus
> sd_read_block_limits() and sd_read_block_characteristics(), I'm
> directing these questions to you.
> 
> Is there some reason for not accounting for the 4 header bytes in the 
> allocation length value stored in the CDB?  Or is this simply a bug?
> 
> Were you aware that SCSI-2 defines the allocation length to be a single 
> byte?  cmd[3] is specified as "Reserved" in the spec.  Hence the value 
> of "len" should be capped at 255 if sdev->scsi_level <= SCSI_2, right?
> 
> Why does scsi_get_vpd_page() retrieve page 0 first, rather than 
> directly asking for the page in question?  Is this some sort of 
> play-it-safe approach, to avoid sending devices commands they may not 
> support?
> 
> Have you considered that plenty of low-budget USB mass-storage devices
> don't implement VPD properly?  I've got a flash drive right here which
> totally ignores the "page" byte in the INQUIRY command; it always
> responds with the normal INQUIRY data.  Thus expecting the response
> data always to be accurate may not be a good idea.  I'm considering
> adding a "restrict_to_MS_usb" flag to the host template, to indicate
> that commands shouldn't be sent unless some version of Windows uses
> them when talking to USB devices -- do you think that could work?
> 
> Finally, what's your opinion on the proposed patch below?
> 
> Alan Stern
> 
> 
> 
> Index: usb-2.6/drivers/scsi/scsi.c
> ===================================================================
> --- usb-2.6.orig/drivers/scsi/scsi.c
> +++ usb-2.6/drivers/scsi/scsi.c
> @@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
>   * @sdev: The device to ask
>   * @buffer: Where to put the result
>   * @page: Which Vital Product Data to return
> - * @len: The length of the buffer
> + * @len: The length of the data (= buffer length - 4)
>   *
>   * This is an internal helper function.  You probably want to use
>   * scsi_get_vpd_page instead.
> @@ -982,6 +982,12 @@ static int scsi_vpd_inquiry(struct scsi_
>  	int result;
>  	unsigned char cmd[16];
>  
> +	len += 4;		/* Include room for the header bytes */
> +
> +	/* SCSI-2 and earlier allow only 1 byte for the allocation length */
> +	if (sdev->scsi_level <= SCSI_2)
> +		len = min(len, 255u);
> +
>  	cmd[0] = INQUIRY;
>  	cmd[1] = 1;		/* EVPD */
>  	cmd[2] = page;
> @@ -994,7 +1000,7 @@ static int scsi_vpd_inquiry(struct scsi_
>  	 * all the existing users tried this hard.
>  	 */
>  	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
> -				  len + 4, NULL, 30 * HZ, 3, NULL);
> +				  len, NULL, 30 * HZ, 3, NULL);
>  	if (result)
>  		return result;
>  
> 

This is certainly a bug. Otherwise I would get all my pages 4 bytes short
and wonder why.

I wish the bug would explain that stupid USB device Martin was fixing.
"I die if evpd page=0 is read" is a very brain dead thing. But there
is no overflow in current code, only underflow.

If you are at it could you please fix all the bugs in this code: ;-)

---
git diff --stat -p drivers/scsi/scsi.c
 drivers/scsi/scsi.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2de5f3a..aca26a1 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -982,6 +982,14 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	int result;
 	unsigned char cmd[16];
 
+	buffer[1] = ~page;
+
+	len += 4;		/* Include room for the header bytes */
+
+	/* SCSI-2 and earlier allow only 1 byte for the allocation length */
+	if (sdev->scsi_level <= SCSI_2)
+		len = min(len, 255u);
+
 	cmd[0] = INQUIRY;
 	cmd[1] = 1;		/* EVPD */
 	cmd[2] = page;
@@ -994,7 +1002,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL);
 	if (result)
 		return result;
 

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 22:47             ` Martin K. Petersen
@ 2009-08-11 14:35               ` Alan Stern
  0 siblings, 0 replies; 24+ messages in thread
From: Alan Stern @ 2009-08-11 14:35 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: Matthew Wilcox, SCSI development list

On Mon, 10 Aug 2009, Martin K. Petersen wrote:

> >>>>> "Alan" == Alan Stern <stern@rowland.harvard.edu> writes:
> 
> Alan,
> 
> >> If the bridge doesn't provide the SCSI rev. where does it come from?
> >> Or are you saying there's a USB "target" chip and then a USB-SATA
> >> bridge chip behind it?
> 
> Alan> There's the bridge chip and the drive itself.  The drive provides
> Alan> the INQUIRY data and the chip provides the USB identifiers.
> 
> But the drive is ATA.  It must be the bridge that translates whatever
> the drive reports in IDENTIFY DEVICE into something that makes sense in
> the SPC/SBC universe.

Right.  The drive provides the data, and the bridge massages it into
the form of an INQUIRY response and sends it back to the host.

Alan Stern


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11  7:07 ` Boaz Harrosh
@ 2009-08-11 14:53   ` Alan Stern
  2009-08-11 15:13     ` James Bottomley
  0 siblings, 1 reply; 24+ messages in thread
From: Alan Stern @ 2009-08-11 14:53 UTC (permalink / raw)
  To: Boaz Harrosh
  Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list,
	James Bottomley

On Tue, 11 Aug 2009, Boaz Harrosh wrote:

> This is certainly a bug. Otherwise I would get all my pages 4 bytes short
> and wonder why.
> 
> I wish the bug would explain that stupid USB device Martin was fixing.
> "I die if evpd page=0 is read" is a very brain dead thing. But there
> is no overflow in current code, only underflow.
> 
> If you are at it could you please fix all the bugs in this code: ;-)

The USB problem shouldn't affect anything thanks to Martin's other
changes (sd won't read VPD for devices with scsi_level <= SCSI_2).  So
how does this revised patch look?

Alan Stern


Index: usb-2.6/drivers/scsi/scsi.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi.c
+++ usb-2.6/drivers/scsi/scsi.c
@@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
  * @sdev: The device to ask
  * @buffer: Where to put the result
  * @page: Which Vital Product Data to return
- * @len: The length of the buffer
+ * @len: The length of the data (= buffer length - 4)
  *
  * This is an internal helper function.  You probably want to use
  * scsi_get_vpd_page instead.
@@ -980,7 +980,10 @@ static int scsi_vpd_inquiry(struct scsi_
 							u8 page, unsigned len)
 {
 	int result;
-	unsigned char cmd[16];
+	int resid;
+	unsigned char cmd[6];
+
+	len += 4;		/* Include room for the header bytes */
 
 	cmd[0] = INQUIRY;
 	cmd[1] = 1;		/* EVPD */
@@ -989,17 +992,19 @@ static int scsi_vpd_inquiry(struct scsi_
 	cmd[4] = len & 0xff;
 	cmd[5] = 0;		/* Control byte */
 
+	buffer[1] = ~page;
+
 	/*
 	 * I'm not convinced we need to try quite this hard to get VPD, but
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, &resid);
 	if (result)
 		return result;
 
-	/* Sanity check that we got the page back that we asked for */
-	if (buffer[1] != page)
+	/* Sanity check that we got the header and the page we asked for */
+	if (resid > len - 4 || buffer[1] != page)
 		return -EIO;
 
 	return 0;


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 14:53   ` Alan Stern
@ 2009-08-11 15:13     ` James Bottomley
  2009-08-11 15:18       ` Boaz Harrosh
  0 siblings, 1 reply; 24+ messages in thread
From: James Bottomley @ 2009-08-11 15:13 UTC (permalink / raw)
  To: Alan Stern
  Cc: Boaz Harrosh, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 2009-08-11 at 10:53 -0400, Alan Stern wrote:
> On Tue, 11 Aug 2009, Boaz Harrosh wrote:
> 
> > This is certainly a bug. Otherwise I would get all my pages 4 bytes short
> > and wonder why.
> > 
> > I wish the bug would explain that stupid USB device Martin was fixing.
> > "I die if evpd page=0 is read" is a very brain dead thing. But there
> > is no overflow in current code, only underflow.
> > 
> > If you are at it could you please fix all the bugs in this code: ;-)
> 
> The USB problem shouldn't affect anything thanks to Martin's other
> changes (sd won't read VPD for devices with scsi_level <= SCSI_2).  So
> how does this revised patch look?
> 
> Alan Stern
> 
> 
> Index: usb-2.6/drivers/scsi/scsi.c
> ===================================================================
> --- usb-2.6.orig/drivers/scsi/scsi.c
> +++ usb-2.6/drivers/scsi/scsi.c
> @@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
>   * @sdev: The device to ask
>   * @buffer: Where to put the result
>   * @page: Which Vital Product Data to return
> - * @len: The length of the buffer
> + * @len: The length of the data (= buffer length - 4)

Really, no.  The former is the correct (and universally used
definition).  This one you propose is asking for confusion and misuse.

>   *
>   * This is an internal helper function.  You probably want to use
>   * scsi_get_vpd_page instead.
> @@ -980,7 +980,10 @@ static int scsi_vpd_inquiry(struct scsi_
>  							u8 page, unsigned len)
>  {
>  	int result;
> -	unsigned char cmd[16];
> +	int resid;
> +	unsigned char cmd[6];
> +
> +	len += 4;		/* Include room for the header bytes */
>  
>  	cmd[0] = INQUIRY;
>  	cmd[1] = 1;		/* EVPD */
> @@ -989,17 +992,19 @@ static int scsi_vpd_inquiry(struct scsi_
>  	cmd[4] = len & 0xff;
>  	cmd[5] = 0;		/* Control byte */
>  
> +	buffer[1] = ~page;

This is pointless and dangerous:  Some architectures will invalidate
caches for DMA not flush them, so it might not do what you think it
does.

James



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:13     ` James Bottomley
@ 2009-08-11 15:18       ` Boaz Harrosh
  2009-08-11 15:27         ` James Bottomley
  0 siblings, 1 reply; 24+ messages in thread
From: Boaz Harrosh @ 2009-08-11 15:18 UTC (permalink / raw)
  To: James Bottomley
  Cc: Alan Stern, Martin K. Petersen, Matthew Wilcox, SCSI development list

On 08/11/2009 06:13 PM, James Bottomley wrote:
> On Tue, 2009-08-11 at 10:53 -0400, Alan Stern wrote:
>> On Tue, 11 Aug 2009, Boaz Harrosh wrote:
>>
>>> This is certainly a bug. Otherwise I would get all my pages 4 bytes short
>>> and wonder why.
>>>
>>> I wish the bug would explain that stupid USB device Martin was fixing.
>>> "I die if evpd page=0 is read" is a very brain dead thing. But there
>>> is no overflow in current code, only underflow.
>>>
>>> If you are at it could you please fix all the bugs in this code: ;-)
>>
>> The USB problem shouldn't affect anything thanks to Martin's other
>> changes (sd won't read VPD for devices with scsi_level <= SCSI_2).  So
>> how does this revised patch look?
>>
>> Alan Stern
>>
>>
>> Index: usb-2.6/drivers/scsi/scsi.c
>> ===================================================================
>> --- usb-2.6.orig/drivers/scsi/scsi.c
>> +++ usb-2.6/drivers/scsi/scsi.c
>> @@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
>>   * @sdev: The device to ask
>>   * @buffer: Where to put the result
>>   * @page: Which Vital Product Data to return
>> - * @len: The length of the buffer
>> + * @len: The length of the data (= buffer length - 4)
> 
> Really, no.  The former is the correct (and universally used
> definition).  This one you propose is asking for confusion and misuse.
> 

This is what is done today Only documented

If you want to fix it to be the full buffer size the user code
should be fixed

>>   *
>>   * This is an internal helper function.  You probably want to use
>>   * scsi_get_vpd_page instead.
>> @@ -980,7 +980,10 @@ static int scsi_vpd_inquiry(struct scsi_
>>  							u8 page, unsigned len)
>>  {
>>  	int result;
>> -	unsigned char cmd[16];
>> +	int resid;
>> +	unsigned char cmd[6];
>> +
>> +	len += 4;		/* Include room for the header bytes */
>>  
>>  	cmd[0] = INQUIRY;
>>  	cmd[1] = 1;		/* EVPD */
>> @@ -989,17 +992,19 @@ static int scsi_vpd_inquiry(struct scsi_
>>  	cmd[4] = len & 0xff;
>>  	cmd[5] = 0;		/* Control byte */
>>  
>> +	buffer[1] = ~page;
> 
> This is pointless and dangerous:  Some architectures will invalidate
> caches for DMA not flush them, so it might not do what you think it
> does.
> 

Then you can't do that "after check" either. It's a simple minefield.
What do you suggest?

> James
> 
> 

Boaz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:18       ` Boaz Harrosh
@ 2009-08-11 15:27         ` James Bottomley
  2009-08-11 15:38           ` Alan Stern
  0 siblings, 1 reply; 24+ messages in thread
From: James Bottomley @ 2009-08-11 15:27 UTC (permalink / raw)
  To: Boaz Harrosh
  Cc: Alan Stern, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 2009-08-11 at 18:18 +0300, Boaz Harrosh wrote:
> On 08/11/2009 06:13 PM, James Bottomley wrote:
> > On Tue, 2009-08-11 at 10:53 -0400, Alan Stern wrote:
> >> On Tue, 11 Aug 2009, Boaz Harrosh wrote:
> >>
> >>> This is certainly a bug. Otherwise I would get all my pages 4 bytes short
> >>> and wonder why.
> >>>
> >>> I wish the bug would explain that stupid USB device Martin was fixing.
> >>> "I die if evpd page=0 is read" is a very brain dead thing. But there
> >>> is no overflow in current code, only underflow.
> >>>
> >>> If you are at it could you please fix all the bugs in this code: ;-)
> >>
> >> The USB problem shouldn't affect anything thanks to Martin's other
> >> changes (sd won't read VPD for devices with scsi_level <= SCSI_2).  So
> >> how does this revised patch look?
> >>
> >> Alan Stern
> >>
> >>
> >> Index: usb-2.6/drivers/scsi/scsi.c
> >> ===================================================================
> >> --- usb-2.6.orig/drivers/scsi/scsi.c
> >> +++ usb-2.6/drivers/scsi/scsi.c
> >> @@ -969,7 +969,7 @@ EXPORT_SYMBOL(scsi_track_queue_full);
> >>   * @sdev: The device to ask
> >>   * @buffer: Where to put the result
> >>   * @page: Which Vital Product Data to return
> >> - * @len: The length of the buffer
> >> + * @len: The length of the data (= buffer length - 4)
> > 
> > Really, no.  The former is the correct (and universally used
> > definition).  This one you propose is asking for confusion and misuse.
> > 
> 
> This is what is done today Only documented
> 
> If you want to fix it to be the full buffer size the user code
> should be fixed

Right.

> >>   *
> >>   * This is an internal helper function.  You probably want to use
> >>   * scsi_get_vpd_page instead.
> >> @@ -980,7 +980,10 @@ static int scsi_vpd_inquiry(struct scsi_
> >>  							u8 page, unsigned len)
> >>  {
> >>  	int result;
> >> -	unsigned char cmd[16];
> >> +	int resid;
> >> +	unsigned char cmd[6];
> >> +
> >> +	len += 4;		/* Include room for the header bytes */
> >>  
> >>  	cmd[0] = INQUIRY;
> >>  	cmd[1] = 1;		/* EVPD */
> >> @@ -989,17 +992,19 @@ static int scsi_vpd_inquiry(struct scsi_
> >>  	cmd[4] = len & 0xff;
> >>  	cmd[5] = 0;		/* Control byte */
> >>  
> >> +	buffer[1] = ~page;
> > 
> > This is pointless and dangerous:  Some architectures will invalidate
> > caches for DMA not flush them, so it might not do what you think it
> > does.
> > 
> 
> Then you can't do that "after check" either. It's a simple minefield.
> What do you suggest?

Well, nothing really, like the original code.  Byzantine checking is
never a good idea.  You always assume that if a device told you it did
what you told it, it actually did.  If we find devices that fail this
simple premise, then we get into blacklists and other forms of
nastiness.

James



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:27         ` James Bottomley
@ 2009-08-11 15:38           ` Alan Stern
  2009-08-11 15:57             ` Matthew Wilcox
  2009-08-11 15:59             ` James Bottomley
  0 siblings, 2 replies; 24+ messages in thread
From: Alan Stern @ 2009-08-11 15:38 UTC (permalink / raw)
  To: James Bottomley
  Cc: Boaz Harrosh, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 11 Aug 2009, James Bottomley wrote:

> > > This is pointless and dangerous:  Some architectures will invalidate
> > > caches for DMA not flush them, so it might not do what you think it
> > > does.
> > > 
> > 
> > Then you can't do that "after check" either. It's a simple minefield.
> > What do you suggest?
> 
> Well, nothing really, like the original code.  Byzantine checking is
> never a good idea.  You always assume that if a device told you it did
> what you told it, it actually did.  If we find devices that fail this
> simple premise, then we get into blacklists and other forms of
> nastiness.

Okay, then how about this?

Alan Stern



Index: usb-2.6/drivers/scsi/scsi.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi.c
+++ usb-2.6/drivers/scsi/scsi.c
@@ -980,7 +980,8 @@ static int scsi_vpd_inquiry(struct scsi_
 							u8 page, unsigned len)
 {
 	int result;
-	unsigned char cmd[16];
+	int resid;
+	unsigned char cmd[6];
 
 	cmd[0] = INQUIRY;
 	cmd[1] = 1;		/* EVPD */
@@ -994,12 +995,12 @@ static int scsi_vpd_inquiry(struct scsi_
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, &resid);
 	if (result)
 		return result;
 
-	/* Sanity check that we got the page back that we asked for */
-	if (buffer[1] != page)
+	/* Sanity check that we at least got the header */
+	if (resid > len - 4)
 		return -EIO;
 
 	return 0;
@@ -1027,7 +1028,7 @@ unsigned char *scsi_get_vpd_page(struct 
 		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
+	result = scsi_vpd_inquiry(sdev, buf, 0, 255 + 4);
 	if (result)
 		goto fail;
 
@@ -1042,7 +1043,7 @@ unsigned char *scsi_get_vpd_page(struct 
 	goto fail;
 
  found:
-	result = scsi_vpd_inquiry(sdev, buf, page, 255);
+	result = scsi_vpd_inquiry(sdev, buf, page, 255 + 4);
 	if (result)
 		goto fail;
 
@@ -1056,7 +1057,7 @@ unsigned char *scsi_get_vpd_page(struct 
 
 	kfree(buf);
 	buf = kmalloc(len + 4, GFP_KERNEL);
-	result = scsi_vpd_inquiry(sdev, buf, page, len);
+	result = scsi_vpd_inquiry(sdev, buf, page, len + 4);
 	if (result)
 		goto fail;
 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:38           ` Alan Stern
@ 2009-08-11 15:57             ` Matthew Wilcox
  2009-08-11 15:59             ` James Bottomley
  1 sibling, 0 replies; 24+ messages in thread
From: Matthew Wilcox @ 2009-08-11 15:57 UTC (permalink / raw)
  To: Alan Stern
  Cc: James Bottomley, Boaz Harrosh, Martin K. Petersen,
	Matthew Wilcox, SCSI development list

On Tue, Aug 11, 2009 at 11:38:03AM -0400, Alan Stern wrote:
> Okay, then how about this?

Crap.  Try this instead.

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2de5f3a..e39d00a 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL);
 	if (result)
 		return result;
 
@@ -1020,14 +1020,20 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 {
 	int i, result;
-	unsigned int len;
-	unsigned char *buf = kmalloc(259, GFP_KERNEL);
+	unsigned int len, alloc;
+	unsigned char *buf;
+
+	/* SCSI-2 only permits 255 bytes of information to be provided */
+	alloc = 259;
+	if (sdev->scsi_level <= SCSI_2)
+		alloc = 255;
 
+	buf = kmalloc(alloc, GFP_KERNEL);
 	if (!buf)
 		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
+	result = scsi_vpd_inquiry(sdev, buf, 0, alloc);
 	if (result)
 		goto fail;
 
@@ -1042,7 +1048,7 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 	goto fail;
 
  found:
-	result = scsi_vpd_inquiry(sdev, buf, page, 255);
+	result = scsi_vpd_inquiry(sdev, buf, page, alloc);
 	if (result)
 		goto fail;
 
@@ -1050,12 +1056,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 	 * Some pages are longer than 255 bytes.  The actual length of
 	 * the page is returned in the header.
 	 */
-	len = (buf[2] << 8) | buf[3];
-	if (len <= 255)
+	len = ((buf[2] << 8) | buf[3]) + 4;
+	if (len <= alloc)
 		return buf;
 
 	kfree(buf);
-	buf = kmalloc(len + 4, GFP_KERNEL);
+	buf = kmalloc(len, GFP_KERNEL);
 	result = scsi_vpd_inquiry(sdev, buf, page, len);
 	if (result)
 		goto fail;

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:38           ` Alan Stern
  2009-08-11 15:57             ` Matthew Wilcox
@ 2009-08-11 15:59             ` James Bottomley
  2009-08-11 16:14               ` Alan Stern
  1 sibling, 1 reply; 24+ messages in thread
From: James Bottomley @ 2009-08-11 15:59 UTC (permalink / raw)
  To: Alan Stern
  Cc: Boaz Harrosh, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 2009-08-11 at 11:38 -0400, Alan Stern wrote:
> On Tue, 11 Aug 2009, James Bottomley wrote:
> 
> > > > This is pointless and dangerous:  Some architectures will invalidate
> > > > caches for DMA not flush them, so it might not do what you think it
> > > > does.
> > > > 
> > > 
> > > Then you can't do that "after check" either. It's a simple minefield.
> > > What do you suggest?
> > 
> > Well, nothing really, like the original code.  Byzantine checking is
> > never a good idea.  You always assume that if a device told you it did
> > what you told it, it actually did.  If we find devices that fail this
> > simple premise, then we get into blacklists and other forms of
> > nastiness.
> 
> Okay, then how about this?
> 
> Alan Stern
> 
> 
> 
> Index: usb-2.6/drivers/scsi/scsi.c
> ===================================================================
> --- usb-2.6.orig/drivers/scsi/scsi.c
> +++ usb-2.6/drivers/scsi/scsi.c
> @@ -980,7 +980,8 @@ static int scsi_vpd_inquiry(struct scsi_
>  							u8 page, unsigned len)
>  {
>  	int result;
> -	unsigned char cmd[16];
> +	int resid;
> +	unsigned char cmd[6];
>  
>  	cmd[0] = INQUIRY;
>  	cmd[1] = 1;		/* EVPD */
> @@ -994,12 +995,12 @@ static int scsi_vpd_inquiry(struct scsi_
>  	 * all the existing users tried this hard.
>  	 */
>  	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
> -				  len + 4, NULL, 30 * HZ, 3, NULL);
> +				  len, NULL, 30 * HZ, 3, &resid);
>  	if (result)
>  		return result;
>  
> -	/* Sanity check that we got the page back that we asked for */
> -	if (buffer[1] != page)
> +	/* Sanity check that we at least got the header */
> +	if (resid > len - 4)
>  		return -EIO;
>  
>  	return 0;
> @@ -1027,7 +1028,7 @@ unsigned char *scsi_get_vpd_page(struct 
>  		return NULL;
>  
>  	/* Ask for all the pages supported by this device */
> -	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
> +	result = scsi_vpd_inquiry(sdev, buf, 0, 255 + 4);
>  	if (result)
>  		goto fail;
>  
> @@ -1042,7 +1043,7 @@ unsigned char *scsi_get_vpd_page(struct 
>  	goto fail;
>  
>   found:
> -	result = scsi_vpd_inquiry(sdev, buf, page, 255);
> +	result = scsi_vpd_inquiry(sdev, buf, page, 255 + 4);
>  	if (result)
>  		goto fail;
>  
> @@ -1056,7 +1057,7 @@ unsigned char *scsi_get_vpd_page(struct 
>  
>  	kfree(buf);
>  	buf = kmalloc(len + 4, GFP_KERNEL);
> -	result = scsi_vpd_inquiry(sdev, buf, page, len);
> +	result = scsi_vpd_inquiry(sdev, buf, page, len + 4);
>  	if (result)
>  		goto fail;

Sort of, but it's not really doing it properly.  Lets do it like this.
This should also fix the > 255 length problem older devices might have.

James

---

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2de5f3a..b6e0307 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL);
 	if (result)
 		return result;
 
@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 {
 	int i, result;
 	unsigned int len;
-	unsigned char *buf = kmalloc(259, GFP_KERNEL);
+	const unsigned int init_vpd_len = 255;
+	unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
 
 	if (!buf)
 		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
+	result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
 	if (result)
 		goto fail;
 
@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 	 * Some pages are longer than 255 bytes.  The actual length of
 	 * the page is returned in the header.
 	 */
-	len = (buf[2] << 8) | buf[3];
-	if (len <= 255)
+	len = ((buf[2] << 8) | buf[3]) + 4;
+	if (len <= init_vpd_len)
 		return buf;
 
 	kfree(buf);
-	buf = kmalloc(len + 4, GFP_KERNEL);
+	buf = kmalloc(len, GFP_KERNEL);
 	result = scsi_vpd_inquiry(sdev, buf, page, len);
 	if (result)
 		goto fail;



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-10 15:32   ` Alan Stern
  2009-08-10 17:08     ` Martin K. Petersen
@ 2009-08-11 16:04     ` Matthew Wilcox
  1 sibling, 0 replies; 24+ messages in thread
From: Matthew Wilcox @ 2009-08-11 16:04 UTC (permalink / raw)
  To: Alan Stern; +Cc: Martin K. Petersen, Matthew Wilcox, SCSI development list

On Mon, Aug 10, 2009 at 11:32:00AM -0400, Alan Stern wrote:
> > > Is there some reason for not accounting for the 4 header bytes in the 
> > > allocation length value stored in the CDB?  Or is this simply a bug?
> > 
> > Um, we do.
> > 
> > unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
> >         unsigned char *buf = kmalloc(259, GFP_KERNEL);
> >         result = scsi_vpd_inquiry(sdev, buf, 0, 255);
> >         for (i = 0; i < buf[3]; i++)
> >                 if (buf[i + 4] == page)
> >                         goto found;
> >         buf = kmalloc(len + 4, GFP_KERNEL);
> >         result = scsi_vpd_inquiry(sdev, buf, page, len);
> 
> I'm not referring to this routine; I'm talking about the code in 
> scsi_vpd_inquiry() where the CDB is set.

You could have been a little clearer in your bug report.

> > > Were you aware that SCSI-2 defines the allocation length to be a single 
> > > byte?  cmd[3] is specified as "Reserved" in the spec.  Hence the value 
> > > of "len" should be capped at 255 if sdev->scsi_level <= SCSI_2, right?
> > 
> > and 'Reserved' in SCSI-2 means:
> > 
> > "A reserved bit, field, or byte shall be set to zero, or in accordance
> > with a future extension to this standard." (7.1.1)
> 
> Sure.  But what reason could there possibly be for making a field
> non-zero when you know that the device won't be able to interpret the
> value correctly?  The fact that sdev->scsi_level == SCSI_2 means
> the device follows _this_ version of the standard, not a future 
> extension.  Or am I missing something?

Because with my misunderstanding of the allocation length to be the page
length, we wouldn't ever request more than 255 bytes until the device
said it supported a page which is more than 255 bytes long.  Since such
a device must be outside the SCSI-2 spec, it was assumed to understand
the meaning of the 'reserved' byte.  So that wasn't a bug.

Now that we need to pass 259 to get 255 bytes, that would be a bug,
so we need to take care of it.

> (And there's no reason to be rude.  I'm trying to hold a civil
> discussion.)

It didn't feel like it.

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 15:59             ` James Bottomley
@ 2009-08-11 16:14               ` Alan Stern
  2009-08-11 16:24                 ` James Bottomley
  0 siblings, 1 reply; 24+ messages in thread
From: Alan Stern @ 2009-08-11 16:14 UTC (permalink / raw)
  To: James Bottomley
  Cc: Boaz Harrosh, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 11 Aug 2009, James Bottomley wrote:

> Sort of, but it's not really doing it properly.  Lets do it like this.
> This should also fix the > 255 length problem older devices might have.

Do you mind including also the residue check?

Alan Stern



Index: usb-2.6/drivers/scsi/scsi.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi.c
+++ usb-2.6/drivers/scsi/scsi.c
@@ -980,7 +980,8 @@ static int scsi_vpd_inquiry(struct scsi_
 							u8 page, unsigned len)
 {
 	int result;
-	unsigned char cmd[16];
+	int resid;
+	unsigned char cmd[6];
 
 	cmd[0] = INQUIRY;
 	cmd[1] = 1;		/* EVPD */
@@ -994,12 +995,12 @@ static int scsi_vpd_inquiry(struct scsi_
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, &resid);
 	if (result)
 		return result;
 
-	/* Sanity check that we got the page back that we asked for */
-	if (buffer[1] != page)
+	/* Sanity check that we got the header and the page we asked for */
+	if (resid > len - 4 || buffer[1] != page)
 		return -EIO;
 
 	return 0;
@@ -1021,13 +1022,14 @@ unsigned char *scsi_get_vpd_page(struct 
 {
 	int i, result;
 	unsigned int len;
-	unsigned char *buf = kmalloc(259, GFP_KERNEL);
+	const unsigned int init_vpd_len = 255;
+	unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
 
 	if (!buf)
 		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
+	result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
 	if (result)
 		goto fail;
 
@@ -1042,7 +1044,7 @@ unsigned char *scsi_get_vpd_page(struct 
 	goto fail;
 
  found:
-	result = scsi_vpd_inquiry(sdev, buf, page, 255);
+	result = scsi_vpd_inquiry(sdev, buf, page, init_vpd_len);
 	if (result)
 		goto fail;
 
@@ -1050,12 +1052,12 @@ unsigned char *scsi_get_vpd_page(struct 
 	 * Some pages are longer than 255 bytes.  The actual length of
 	 * the page is returned in the header.
 	 */
-	len = (buf[2] << 8) | buf[3];
-	if (len <= 255)
+	len = ((buf[2] << 8) | buf[3]) + 4;
+	if (len <= init_vpd_len)
 		return buf;
 
 	kfree(buf);
-	buf = kmalloc(len + 4, GFP_KERNEL);
+	buf = kmalloc(len, GFP_KERNEL);
 	result = scsi_vpd_inquiry(sdev, buf, page, len);
 	if (result)
 		goto fail;


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 16:14               ` Alan Stern
@ 2009-08-11 16:24                 ` James Bottomley
  2009-08-13 13:58                   ` Boaz Harrosh
  0 siblings, 1 reply; 24+ messages in thread
From: James Bottomley @ 2009-08-11 16:24 UTC (permalink / raw)
  To: Alan Stern
  Cc: Boaz Harrosh, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Tue, 2009-08-11 at 12:14 -0400, Alan Stern wrote:
> On Tue, 11 Aug 2009, James Bottomley wrote:
> 
> > Sort of, but it's not really doing it properly.  Lets do it like this.
> > This should also fix the > 255 length problem older devices might have.
> 
> Do you mind including also the residue check?

But there's no point to it ... it's a Byzantine check.  The standard
says shall return as many bytes as will fit in the allocation length
(what it does with allocation length beyond data to return is
undefined).

For the USB case where a full residue and no error indicates there was
actually an error, we already have a translation.

If devices just return random data lengths and then stop, your proposed
residue check doesn't catch them anyway.  However, I'd much rather
assume a device performs to spec until proven otherwise.

James



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-11 16:24                 ` James Bottomley
@ 2009-08-13 13:58                   ` Boaz Harrosh
  2009-08-13 14:15                     ` James Bottomley
  0 siblings, 1 reply; 24+ messages in thread
From: Boaz Harrosh @ 2009-08-13 13:58 UTC (permalink / raw)
  To: James Bottomley
  Cc: Alan Stern, Martin K. Petersen, Matthew Wilcox, SCSI development list

On 08/11/2009 07:24 PM, James Bottomley wrote:
> On Tue, 2009-08-11 at 12:14 -0400, Alan Stern wrote:
>> On Tue, 11 Aug 2009, James Bottomley wrote:
>>
>>> Sort of, but it's not really doing it properly.  Lets do it like this.
>>> This should also fix the > 255 length problem older devices might have.
>>
>> Do you mind including also the residue check?
> 
> But there's no point to it ... it's a Byzantine check.  The standard
> says shall return as many bytes as will fit in the allocation length
> (what it does with allocation length beyond data to return is
> undefined).
> 
> For the USB case where a full residue and no error indicates there was
> actually an error, we already have a translation.
> 
> If devices just return random data lengths and then stop, your proposed
> residue check doesn't catch them anyway.  However, I'd much rather
> assume a device performs to spec until proven otherwise.
> 

OK so this is also the case for devices that did not error, did not return
resid, and yet did not return the page in question. Please remove that
!= page check then. ("until proven otherwise")

> James
> 
> 

Boaz

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Bugs in scsi_vpd_inquiry()
  2009-08-13 13:58                   ` Boaz Harrosh
@ 2009-08-13 14:15                     ` James Bottomley
  0 siblings, 0 replies; 24+ messages in thread
From: James Bottomley @ 2009-08-13 14:15 UTC (permalink / raw)
  To: Boaz Harrosh
  Cc: Alan Stern, Martin K. Petersen, Matthew Wilcox, SCSI development list

On Thu, 2009-08-13 at 16:58 +0300, Boaz Harrosh wrote:
> On 08/11/2009 07:24 PM, James Bottomley wrote:
> > On Tue, 2009-08-11 at 12:14 -0400, Alan Stern wrote:
> >> On Tue, 11 Aug 2009, James Bottomley wrote:
> >>
> >>> Sort of, but it's not really doing it properly.  Lets do it like this.
> >>> This should also fix the > 255 length problem older devices might have.
> >>
> >> Do you mind including also the residue check?
> > 
> > But there's no point to it ... it's a Byzantine check.  The standard
> > says shall return as many bytes as will fit in the allocation length
> > (what it does with allocation length beyond data to return is
> > undefined).
> > 
> > For the USB case where a full residue and no error indicates there was
> > actually an error, we already have a translation.
> > 
> > If devices just return random data lengths and then stop, your proposed
> > residue check doesn't catch them anyway.  However, I'd much rather
> > assume a device performs to spec until proven otherwise.
> > 
> 
> OK so this is also the case for devices that did not error, did not return
> resid, and yet did not return the page in question. Please remove that
> != page check then. ("until proven otherwise")

The usual presumption is that if a check is there, there's a reason for
it.  There are actually several devices that only return the one VPD
page they're programmed for whatever you happen to ask for ... that's
why the check is there.

James



^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2009-08-13 14:15 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-10 14:41 Bugs in scsi_vpd_inquiry() Alan Stern
2009-08-10 14:58 ` Matthew Wilcox
2009-08-10 15:32   ` Alan Stern
2009-08-10 17:08     ` Martin K. Petersen
2009-08-10 20:13       ` Alan Stern
2009-08-10 20:49         ` Martin K. Petersen
2009-08-10 21:14           ` Alan Stern
2009-08-10 22:47             ` Martin K. Petersen
2009-08-11 14:35               ` Alan Stern
2009-08-10 21:53       ` Douglas Gilbert
2009-08-10 22:52         ` Martin K. Petersen
2009-08-11 16:04     ` Matthew Wilcox
2009-08-11  7:07 ` Boaz Harrosh
2009-08-11 14:53   ` Alan Stern
2009-08-11 15:13     ` James Bottomley
2009-08-11 15:18       ` Boaz Harrosh
2009-08-11 15:27         ` James Bottomley
2009-08-11 15:38           ` Alan Stern
2009-08-11 15:57             ` Matthew Wilcox
2009-08-11 15:59             ` James Bottomley
2009-08-11 16:14               ` Alan Stern
2009-08-11 16:24                 ` James Bottomley
2009-08-13 13:58                   ` Boaz Harrosh
2009-08-13 14:15                     ` James Bottomley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.