linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATCH: Off-by-one bug in user page calculations for Direct I/O
@ 2003-11-16 17:04 Alan Stern
  2003-11-17 10:49 ` Jens Axboe
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Stern @ 2003-11-16 17:04 UTC (permalink / raw)
  To: Kai.Makisara, Douglas Gilbert; +Cc: SCSI development list

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)


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

* Re: PATCH: Off-by-one bug in user page calculations for Direct I/O
  2003-11-16 17:04 PATCH: Off-by-one bug in user page calculations for Direct I/O Alan Stern
@ 2003-11-17 10:49 ` Jens Axboe
  0 siblings, 0 replies; 3+ messages in thread
From: Jens Axboe @ 2003-11-17 10:49 UTC (permalink / raw)
  To: Alan Stern; +Cc: Kai.Makisara, Douglas Gilbert, SCSI development list

On Sun, Nov 16 2003, Alan Stern wrote:
> 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".

Good catch, that's a classic error. page calculations 101? :)

-- 
Jens Axboe


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

* Re: PATCH: Off-by-one bug in user page calculations for Direct I/O
       [not found] <Pine.LNX.4.58.0311162341040.17544@kai.makisara.local>
@ 2003-11-17 15:01 ` Alan Stern
  0 siblings, 0 replies; 3+ messages in thread
From: Alan Stern @ 2003-11-17 15:01 UTC (permalink / raw)
  To: James Bottomley; +Cc: SCSI development list

James:

Please apply the patch below to the scsi-bugfixes-2.6 tree.

Alan Stern


On Sun, 16 Nov 2003, Kai Makisara wrote:

> On Sun, 16 Nov 2003, Alan Stern wrote:
> 
> > 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
> 
> Your analysis is correct and this is a bug. Could you send the fix to
> James Bottomley for inclusion into the scsi-bugfixes-2.6 bk tree (at least
> the st part).
> 
> Thanks for noticing the bug.
> 
> 	Kai
> 
> P.S. I usually write these ((base ~ mask) + count + PAGE_SIZE - 1) >>
> PAGE_SHIFT. I don't know why I did it like this here. One should never try
> to be clever and do something in a new way or copy something that does not
> match one's own standard ways of doing things ;-)

On Mon, 17 Nov 2003, Douglas Gilbert wrote:

> Alan,
> ... and the sg part as well ..
> 
> > Thanks for noticing the bug.
> 
> dito
> 
> Doug Gilbert


===== sg.c 1.48 vs edited =====
--- 1.48/drivers/scsi/sg.c	Fri Oct 24 14:53:37 2003
+++ edited/drivers/scsi/sg.c	Mon Nov 17 09:57:36 2003
@@ -1627,7 +1627,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)
===== st.c 1.45 vs edited =====
--- 1.45/drivers/scsi/st.c	Fri Sep  5 12:16:40 2003
+++ edited/drivers/scsi/st.c	Mon Nov 17 09:57:09 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)


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

end of thread, other threads:[~2003-11-17 15:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-16 17:04 PATCH: Off-by-one bug in user page calculations for Direct I/O Alan Stern
2003-11-17 10:49 ` Jens Axboe
     [not found] <Pine.LNX.4.58.0311162341040.17544@kai.makisara.local>
2003-11-17 15:01 ` Alan Stern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).