Re: sendfile -EOVERFLOW on AMD64

From: Andi Kleen
Date: Wed May 19 2004 - 07:58:21 EST


> The userland prototypes are:
> extern ssize_t sendfile (int __out_fd, int __in_fd, off_t *__offset,
> size_t __count) __THROW;
> extern ssize_t sendfile64 (int __out_fd, int __in_fd, __off64_t *__offset,
> size_t __count) __THROW;
> Thus you really cannot transfer more than 4G-1 bytes in one call on 32-bit
> arches.

True.

> Actually, already any counts >= 2GB-1 might be problematic, but we are
> there on the same boat as with e.g. read(2). For read, POSIX says:
> "If the value of nbyte is greater than {SSIZE_MAX}, the result is
> implementation-defined."
> so portable programs really shouldn't try to transfer more than that
> in one go but the kernel certainly should try to handle sizes up to
> SIZE_MAX-4096 or something like that.

Hmm, ssize_t is signed. If there are any if (ret < 0) checks in the
kernel it will fail too. So the real limit would be 0x7fffffff

Perhaps that should be enforced like this?


diff -u linux/fs/read_write.c-o linux/fs/read_write.c
--- linux/fs/read_write.c-o 2004-05-18 10:55:54.000000000 +0200
+++ linux/fs/read_write.c 2004-05-19 14:57:06.000000000 +0200
@@ -700,6 +700,9 @@
off_t off;
ssize_t ret;

+ if (sizeof(size_t) == 4 && (int)count < 0)
+ return -EOVERFLOW;
+
if (offset) {
if (unlikely(get_user(off, offset)))
return -EFAULT;
@@ -718,6 +721,9 @@
loff_t pos;
ssize_t ret;

+ if (sizeof(size_t) == 4 && (int)count < 0)
+ return -EOVERFLOW;
+
if (offset) {
if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
return -EFAULT;

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/