[Summary of problem: when attempting to read more data than are
available from an USB scanner connected to an UHCI port on a new
2.3.99 kernel, we get a hang.  For example read(fd, buffer, 6) hangs
if only 4 bytes are available, rather than returing the 4 bytes that
are available. Reading more data than is available is unfortunately
necessary in situations where the exact amount of data is unknown in
advance...]

It turns out that the problem was introduced by the following change,
included in the 2.3.46 patch:

diff -u --recursive --new-file v2.3.45/linux/drivers/usb/scanner.c linux/drivers
--- v2.3.45/linux/drivers/usb/scanner.c Thu Feb 10 17:11:15 2000
+++ linux/drivers/usb/scanner.c Wed Feb 16 10:35:08 2000
@@ -382,24 +406,22 @@
 #endif

                if (partial) { /* Data returned */
-                       count = this_read = partial;
-               } else {
-                       ret = 0;
-                       read_count = 0;
-                       break;
-               }
-
-               if (this_read) {
                        if (copy_to_user(buffer, ibuf, this_read)) {
                                ret = -EFAULT;
                                break;
                        }
-                       count -= this_read;
-                       read_count += this_read;
-                       buffer += this_read;
+                       count -= partial;
+                       bytes_read += partial;
+                       buffer += partial;
+
+               } else {
+                       ret = 0;
+                       break;
                }
+
        }
-       return ret ? ret : read_count;
+
+       return ret ? ret : bytes_read;
 }




Formerly, the read returned after one chunk (because basically, count
was first set equal to partial, and then partial was substracted from
count, resulting in an end of the loop).

Right now, count is not touched, and the read_scanner loop tries to
read a second chunk, while now no data is available at all: the
low-level code now just behaves the same way as a pipe would: it waits
for data, which unfortunately never comes.

There seems to be a second issue: the copy_to_user copies this_read
bytes (requested amount) rather than partial (amount actually read),
which could result in leakage of confidential data from the kernel.


The patch below fixes this problem, however it breaks in the case
where the user asks for more than IBUF_SIZE bytes.  What we'd really
need would be a way to ask the usb-uhci driver whether more data is
waiting... Apparently, this bug doesn't exist for OHCI.  Does OHCI
have a way to check whether the device will send more data, which UHCI
doesn't have?


Regards,

Alain




diff -ur 2.3.99-pre5/linux/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- 2.3.99-pre5/linux/drivers/usb/scanner.c     Mon Apr 24 00:48:38 2000
+++ linux/drivers/usb/scanner.c Mon Apr 24 00:50:07 2000
@@ -436,7 +436,7 @@
 #endif
 
                if (partial) { /* Data returned */
-                       if (copy_to_user(buffer, ibuf, this_read)) {
+                       if (copy_to_user(buffer, ibuf, partial)) {
                                ret = -EFAULT;
                                break;
                        }
@@ -444,10 +444,9 @@
                        bytes_read += partial;
                        buffer += partial;
                        
-               } else {
-                       ret = 0;
-                       break;
                }
+               ret = 0;
+               break;
                
        }
        

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to