All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Mark Glines <mark@glines.org>,
	Matthew Dharm <mdharm-usb@one-eyed-alien.net>,
	James Bottomley <James.Bottomley@SteelEye.com>,
	USB list <linux-usb@vger.kernel.org>,
	linux-scsi <linux-scsi@vger.kernel.org>
Subject: Re: [PATCH] bugfix for an underflow condition in usb storage & isd200.c
Date: Sun, 03 Feb 2008 18:28:48 +0200	[thread overview]
Message-ID: <47A5EBC0.3060401@panasas.com> (raw)
In-Reply-To: <Pine.LNX.4.44L0.0802031025180.12447-100000@netrider.rowland.org>

On Sun, Feb 03 2008 at 18:01 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> Sorry, I understood only about half of what you wrote -- maybe less!
> 
> On Sun, 3 Feb 2008, Boaz Harrosh wrote:
> 
>> On Thu, Jan 31 2008 at 22:56 +0200, Alan Stern <stern@rowland.harvard.edu> wrote:
> 
>>> I still don't understand.  Can you explain exactly what an overflow 
>>> condition (negative residue) really means?
>> As far as the protocol it is an error condition. But it is an error
>> condition that should be handled and io should continue. What it usually means
>> is that either target or Initiator had, like you said, more data then
>> expected. Usually an encoding error of the different stages of transfer
>> like sum of R2Ts or DATA is bigger then CDB length and so on.
>> The important thing is that the system should continue, and that this
>> is not a check_condition error.
> 
> What is an R2T?
> 
> How does a negative residue differ from a Phase error?
> 
> What exactly do you mean by "more data then expected"?  The USB 
> mass-storage protocol specifies the length of a transfer in at least 
> three different places, and those places won't always agree:
> 
>     (1) For some commands, the device may have a specific amount
> 	of data it can supply or expect to receive.  For example,
> 	the device might have 90 bytes of INQUIRY data available.
> 
>     (2) Many CDBs include a field specifying how much data should
> 	be transferred (INQUIRY does).  The amount of data actually
> 	transferred is supposed to be the smaller of this value
> 	and the size in (1).
> 
>     (3) The USB Bulk-only transport includes fields in the CDB
> 	wrapper specifying the number of bytes the host expects to 
> 	transfer and the direction.
> 
> If (3) is different from (2) or if the direction disagrees with what
> the device expects, the device is supposed to return a Phase error.
> If (1) < (2) = (3) then it isn't an error; in this case the residue is
> given by (2) - (1).  If (1) > (2) = (3) then according to the USB
> protocol nothing special happens -- no error and residue = 0.  
> (Note however that the INQUIRY response data includes a field in which 
> the device can tell the host that more data is available.)
> 
> In no cases does this allow for a negative residue.
> 
>>> Does it mean that the device had more data available than the host
>>> asked for?  If it does, then you don't need to change the isd200 code
>>> at all.  The changes to protocol.c will be enough.
>> I do in the sense that the target should return correct information requested.
> 
> Doesn't the existing code in isd200 together with your changes to
> protocol.c do exactly that?
> 
>> overflow is still an error.
> 
> Once again: What exactly do you mean by "overflow"?  In what sense is 
> it an error?
> 
>> A recoverable but none-standard error. The INQUIRY
>> has 3 flavors based on requested size. The target should comply.
> 
> What 3 flavors are you talking about?  As far as I know there's only 
> one type of INQUIRY command.
> 
>>> However you should realize that usb-storage, as it stands, won't work
>>> properly with negative residues.  Look at usb_stor_Bulk_transport() in
>>> transport.c.  The residue variable is declared to be unsigned int.  
>>> There's also code later on in the routine which assumes the residue is
>>> never negative.
>>>
>>> Alan Stern
>>>
>>> -
>> I will change that, but if you don't mind with a FIXME: comment next
>> to it. I will set resid to 1 and set the cmnd->status.
> 
> Where will you change this?  Why set resid to 1?  That means the device 
> sent 1 byte less than the host expected.
> 
>> Setting of command
>> status is ineffective as it is, most probably, been set afterwards.
> 
> After what?
> 
>> Should I also put a WARN_ON()? I would say yes.
>> I'll send a patch.
> 
> Maybe this will be more clear once you do.  As it is, I'm totally in 
> the dark.
> 
> Alan Stern
> 
> -
below is what I have so far. It is for v2.6.24 if it's acceptable then
I'll also send a patch for head-of-line. Please comment.

Boaz

----
>From 3610cfa93c990bbbafb296134ac01ef6d426eb8d Mon Sep 17 00:00:00 2001
From: Boaz Harrosh <bharrosh@panasas.com>
Date: Thu, 31 Jan 2008 21:31:31 +0200
Subject: [PATCH] bugfix for an overflow condition in usb storage & isd200.c

  scsi_scan is issuing a 36-byte INQUIRY request to llds. isd200 would
  volunteer 96 bytes of INQUIRY. This caused an overflow condition in
  protocol.c usb_stor_access_xfer_buf(). So first fix is to
  usb_stor_access_xfer_buf() to properly handle overflow/underflow conditions.
  Then usb_stor_set_xfer_buf() should report this condition as cmnd->result ==
  (DID_BAD_TARGET << 16).

  Then also isd200.c is fixed to only return the type of INQUIRY && SENSE
  the upper layer asked for.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
 drivers/usb/storage/isd200.c   |    7 +++++--
 drivers/usb/storage/protocol.c |   20 ++++++++++++++++----
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 49ba6c0..8186e93 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1238,6 +1238,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
 	unsigned long lba;
 	unsigned long blockCount;
 	unsigned char senseData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+	unsigned xfer_len;
 
 	memset(ataCdb, 0, sizeof(union ata_cdb));
 
@@ -1247,8 +1248,9 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
 		US_DEBUGP("   ATA OUT - INQUIRY\n");
 
 		/* copy InquiryData */
+		xfer_len = min(sizeof(info->InquiryData), scsi_bufflen(srb));
 		usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData,
-				sizeof(info->InquiryData), srb);
+					xfer_len, srb);
 		srb->result = SAM_STAT_GOOD;
 		sendToTransport = 0;
 		break;
@@ -1257,7 +1259,8 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
 		US_DEBUGP("   ATA OUT - SCSIOP_MODE_SENSE\n");
 
 		/* Initialize the return buffer */
-		usb_stor_set_xfer_buf(senseData, sizeof(senseData), srb);
+		xfer_len = min(sizeof(senseData), scsi_bufflen(srb));
+		usb_stor_set_xfer_buf(senseData, xfer_len, srb);
 
 		if (info->DeviceFlags & DF_MEDIA_STATUS_ENABLED)
 		{
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 889622b..f141819 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -194,7 +194,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * and the starting offset within the page, and update
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
-		while (cnt < buflen) {
+		while (cnt < buflen && sg) {
 			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
@@ -248,9 +248,21 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
 {
 	unsigned int offset = 0;
 	struct scatterlist *sg = NULL;
+	unsigned count;
 
-	usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+	count = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
 			TO_XFER_BUF);
-	if (buflen < srb->request_bufflen)
-		srb->resid = srb->request_bufflen - buflen;
+
+	/* Check for overflow */
+	if (buflen > scsi_bufflen(srb)) {
+		/* FIXME: we set resid to 0, and set status. but also put a
+		 * a WARN_ON. The status will most probably not reach upper 
+		 * layer and the WARN_ON is the only indication of this glitch.
+		 */
+		WARN_ON(1);
+		srb->result = (DID_BAD_TARGET << 16);
+		count = scsi_bufflen(srb);
+	}
+
+	scsi_set_resid(srb, scsi_bufflen(srb) - count);
 }
-- 
1.5.3.3




  reply	other threads:[~2008-02-03 16:29 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.LNX.4.44L0.0801301807420.17156-100000@iolanthe.rowland.org>
     [not found] ` <47A1948B.2010402@panasas.com>
     [not found]   ` <20080131070846.4464eb3c@chirp.tahoe>
     [not found]     ` <20080131070846.4464eb3c-uevSgErl2ChVvDCLMmKh5Q@public.gmane.org>
2008-01-31 15:17       ` [linux-usb-devel] 2.6.24: NULL scatter-gather pointer in usb_storage:usb_stor_access_xfer_buf? Boaz Harrosh
2008-01-31 16:45         ` Alan Stern
     [not found]           ` <Pine.LNX.4.44L0.0801311143180.3970-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-01-31 17:20             ` Boaz Harrosh
     [not found]         ` <47A1E6A0.8050500-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 17:19           ` [PATCH] bugfix for an underflow condition in usb storage & isd200.c Boaz Harrosh
     [not found]             ` <47A2033D.2050502-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 17:49               ` Alan Stern
     [not found]                 ` <Pine.LNX.4.44L0.0801311244430.4373-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-01-31 19:00                   ` Boaz Harrosh
2008-01-31 19:34                     ` Alan Stern
2008-01-31 19:53                       ` Boaz Harrosh
2008-01-31 20:56                         ` Alan Stern
     [not found]                           ` <Pine.LNX.4.44L0.0801311546450.22845-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-03  8:59                             ` Boaz Harrosh
     [not found]                               ` <47A5825D.2030901-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-03 16:01                                 ` Alan Stern
2008-02-03 16:28                                   ` Boaz Harrosh [this message]
2008-02-03 19:23                                     ` Matthew Dharm
2008-02-04  9:05                                       ` Boaz Harrosh
2008-02-04 20:05                                       ` Alan Stern
     [not found]                                         ` <Pine.LNX.4.44L0.0802041500420.5186-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-05  8:41                                           ` Boaz Harrosh
     [not found]                                             ` <47A8213B.9050705-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-05 15:42                                               ` Alan Stern
2008-02-05 16:54                                                 ` Boaz Harrosh
2008-02-05 17:54                                         ` Matthew Dharm
     [not found]                                           ` <20080205175403.GA31714-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org>
2008-02-06 20:23                                             ` Alan Stern
2008-02-06 21:05                                               ` Matthew Dharm
2008-02-06 22:18                                                 ` Alan Stern
2008-02-06 23:01                                                   ` James Bottomley
     [not found]                                                     ` <1202338869.3112.138.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-06 23:25                                                       ` Alan Stern
2008-02-06 23:55                                                         ` James Bottomley
     [not found]                                                           ` <1202342108.3112.146.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-07 16:35                                                             ` Alan Stern
2008-02-08 16:46                                             ` Alan Stern
     [not found]                                               ` <Pine.LNX.4.44L0.0802081143010.4593-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
2008-02-08 16:59                                                 ` Mark Glines
     [not found]                                     ` <47A5EBC0.3060401-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-02-03 21:09                                       ` Matthew Dharm
2008-01-31 18:00               ` Greg KH
2008-01-31 18:32                 ` Boaz Harrosh
2008-01-31 19:37                 ` [PATCH 2.6.24] bugfix for an overflow " Boaz Harrosh
     [not found]                   ` <47A22369.80906-C4P08NqkoRlBDgjK7y7TUQ@public.gmane.org>
2008-01-31 19:49                     ` Matthew Dharm
2008-01-31 20:05                       ` Boaz Harrosh
     [not found]                       ` <47A229FF.4040404@panasas.com>
2008-01-31 20:16                         ` Matthew Dharm
2008-02-02  0:55                     ` Mark Glines

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47A5EBC0.3060401@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=James.Bottomley@SteelEye.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mark@glines.org \
    --cc=mdharm-usb@one-eyed-alien.net \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.