hugetlb: unsigned ret cannot be negative.
Subsystems (2)
PATCH 1/1 hugetlb: unsigned ret cannot be negative.
unsigned long ret cannot be negative, but ret can get -EFAULT.
---hugetlbfs_read_actor() returns int,
see
vi fs/hugetlbfs/inode.c +187
fs/hugetlbfs/inode.c +5 -3
@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);
@@ -279,15 +280,16 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr); } -if (ret <0 ) { +if (ra <0 ) {if (retval ==0 ) - retval = ret; + retval = ra;if (page)page_cache_release (page); goto out; } + ret = ra; offset += ret; retval += ret;
Andrew Morton
maintainerQuoted 30 lines · On Sat, 29 Nov 2008 06:36:59 -0500 roel kluin <[email protected]> wrote:
unsigned long ret cannot be negative, but ret can get
-EFAULT.Signed-off-by Roel Kluin <[email protected]>---
hugetlbfs_read_actor()returns int,
see
vifs/hugetlbfs/inode.c+187fs/hugetlbfs/inode.c +3
-2@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);@@ -279,15 +280,16 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr); } -if (ret <0 ) { +if (ra <0 ) {if (retval ==0 )
fs/hugetlbfs/inode.c static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, · line 295
Quoted 10 lines
fs/hugetlbfs/inode.c +2
-1- retval = ret; + retval = ra;if (page)page_cache_release (page); goto out; } + ret = ra; offset += ret; retval += ret;
`ra' can obviously be used uninitialised here. The compiler reports this, too.
PATCH v2 1/1 hugetlb: unsigned ret cannot be negative.
Quoted 21 lines · Andrew Morton
Quoted 18 lines · On Sat, 29 Nov 2008 06:36:59 -0500 roel kluin <[email protected]> wrote:
unsigned long ret cannot be negative, but ret can get
-EFAULT.Signed-off-by Roel Kluin <[email protected]>---
hugetlbfs_read_actor()returns int,
see
vifs/hugetlbfs/inode.c+187fs/hugetlbfs/inode.c +1
-0@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;
Quoted 14 lines
fs/hugetlbfs/inode.c static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, · line 285
Quoted 11 lines
fs/hugetlbfs/inode.c +2
-2/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);@@ -279,15 +280,16 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr); } -if (ret <0 ) { +if (ra <0 ) {`ra' can obviously be used uninitialised here. The compiler reports this, too.
Yes, it was incomplete as well, sorry. This should be OK. (checkpatch tested) --------------->8----------------8<--------------------- unsigned long ret cannot be negative, but ret can get -EFAULT.
---
fs/hugetlbfs/inode.c +8 -4
@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);
@@ -274,16 +275,19 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,*/ ret = len < nr ? len : nr;if (clear_user (buf, ret)) - ret = -EFAULT ; + ra = -EFAULT ; +else + ra =0 ; }else {/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr); + ret = ra; } -if (ret <0 ) { +if (ra <0 ) {if (retval ==0 ) - retval = ret; + retval = ra;if (page)page_cache_release (page); goto out;
Andrew Morton
maintainerQuoted 70 lines · On Tue, 02 Dec 2008 23:51:06 +0100 Roel Kluin <[email protected]> wrote:
Quoted 21 lines · Andrew Morton
Quoted 18 lines · On Sat, 29 Nov 2008 06:36:59 -0500 roel kluin <[email protected]> wrote:
unsigned long ret cannot be negative, but ret can get
-EFAULT.Signed-off-by Roel Kluin <[email protected]>---
hugetlbfs_read_actor()returns int,
see
vifs/hugetlbfs/inode.c+187fs/hugetlbfs/inode.c +1
-0@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;Quoted 14 lines
fs/hugetlbfs/inode.c static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, · line 285
Quoted 11 lines
fs/hugetlbfs/inode.c +2
-2/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);@@ -279,15 +280,16 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr); } -if (ret <0 ) { +if (ra <0 ) {`ra' can obviously be used uninitialised here. The compiler reports this, too.
Yes, it was incomplete as well, sorry. This should be OK. (checkpatch tested) --------------->8----------------8<--------------------- unsigned long ret cannot be negative, but ret can get
-EFAULT.Signed-off-by Roel Kluin <[email protected]>---
fs/hugetlbfs/inode.c +5
-2@@ -252,6 +252,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,for (;;) {struct page *page;unsigned long nr, ret; +int ra;/* nr is the maximum number of bytes to copy from this page */ nr =huge_page_size (h);@@ -274,16 +275,19 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,*/ ret = len < nr ? len : nr;if (clear_user (buf, ret)) - ret = -EFAULT ; + ra = -EFAULT ; +else + ra =0 ; }else {/* * We have the page, copy it to user space buffer. */ - ret =hugetlbfs_read_actor (page, offset, buf, len, nr); + ra =hugetlbfs_read_actor (page, offset, buf, len, nr);
fs/hugetlbfs/inode.c static ssize_t hugetlbfs_read(struct file *filp, char __user *buf, · line 293
Quoted 10 lines
fs/hugetlbfs/inode.c +3
-2+ ret = ra; } -if (ret <0 ) { +if (ra <0 ) {if (retval ==0 ) - retval = ret; + retval = ra;if (page)page_cache_release (page); goto out;
Looks like it'll work, I think.
That function is pretty sad-looking now. It has ra', ret' and retval', all rather confusingly. After being renamed to something useful, ret' should have type size_t, hugetlbfs_read_actor() should return size_t and the whole logic around these three things needs a can of drano tipped down it.
Oh well.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>