The page count calculations in drivers/scsi/st.c (and copied in sg.c) are
wrong. The code says:
nr_pages = ((uaddr & ~PAGE_MASK) + count - 1 + ~PAGE_MASK) >>
PAGE_SHIFT;
That will compute an incorrect value if the user's buffer happens to end
on the first byte of a new page. Example: Suppose uaddr starts right on
a page boundary and count is PAGE_SIZE + 1. Then
(uaddr & ~PAGE_MASK) -> 0
count - 1 -> PAGE_SIZE
~PAGE_MASK -> PAGE_SIZE - 1
nr_pages -> (2 * PAGE_SIZE - 1) >> PAGE_SHIFT = 1
when in fact nr_pages should be 2. Either the "- 1" shouldn't be there or
the second "~PAGE_MASK" should be replaced by "PAGE_SIZE".
Alan Stern
--- a/drivers/scsi/st.c Fri Sep 5 13:58:01 2003
+++ b/drivers/scsi/st.c Sun Nov 16 11:44:47 2003
@@ -4036,7 +4036,7 @@
unsigned int nr_pages;
struct page **pages;
- nr_pages = ((uaddr & ~PAGE_MASK) + count - 1 + ~PAGE_MASK) >>
PAGE_SHIFT;
+ nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
/* User attempted Overflow! */
if ((uaddr + count) < uaddr)
--- a/drivers/scsi/sg.c Mon Oct 20 10:19:01 2003
+++ b/drivers/scsi/sg.c Sun Nov 16 11:45:10 2003
@@ -1625,7 +1625,7 @@
unsigned int nr_pages;
struct page **pages;
- nr_pages = ((uaddr & ~PAGE_MASK) + count - 1 + ~PAGE_MASK) >>
PAGE_SHIFT;
+ nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
/* User attempted Overflow! */
if ((uaddr + count) < uaddr)
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|