[PATCH 4/7] fs: Change error checking logic for fsdrv->lseek() call

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 32-bit systems, cheking for IS_ERR_VALUE(pos) is not
correct. Expanding that code we get (loff_t cast is added for clarity):

 (loff_t)pos >= (unsigned long)-MAX_ERRNO

given that loff_t is a 64-bit signed value, any perfectly valid seek
offset that is greater than 0xffffc000 will result in false
positive. Change the logic to check if position returned by
fsdrv->lseek() is what's been requested. If it is, we can assume that
operation was succesfull. If not, that's likely means failure and
return value is a negative error code.

This should accomodate both 32-bit systems, where we /dev/mem doesn't
present any range problems, as well as 64-bit systems where both file
offset and size of /dev/mem couldn't really be correctly captured by
loff_t and we have to rely on 2's complement and overflow.

Signed-off-by: Andrey Smirnov <andrew.smirnov@xxxxxxxxx>
---
 fs/fs.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index a304bf186..6a62fb98b 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -405,8 +405,7 @@ loff_t lseek(int fildes, loff_t offset, int whence)
 {
 	struct fs_driver_d *fsdrv;
 	FILE *f;
-	loff_t pos;
-	int ret;
+	loff_t pos, ret;
 
 	if (check_fd(fildes))
 		return -1;
@@ -442,13 +441,11 @@ loff_t lseek(int fildes, loff_t offset, int whence)
 		goto out;
 	}
 
-	pos = fsdrv->lseek(&f->fsdev->dev, f, pos);
-	if (IS_ERR_VALUE(pos)) {
-		errno = -pos;
-		return -1;
-	}
+	ret = fsdrv->lseek(&f->fsdev->dev, f, pos);
+	if (ret != pos)
+		goto out;
 
-	return pos;
+	return ret;
 
 out:
 	if (ret)
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux