]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/compat.c
xps: Transmit Packet Steering
[net-next-2.6.git] / fs / compat.c
index 52cfeb61da77c14ce7d3838db7517b5b6f88b213..c580c322fa6b1bab00a8b949cd3284f691bc366a 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/eventpoll.h>
 #include <linux/fs_struct.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -606,14 +607,14 @@ ssize_t compat_rw_copy_check_uvector(int type,
        /*
         * Single unix specification:
         * We should -EINVAL if an element length is not >= 0 and fitting an
-        * ssize_t.  The total length is fitting an ssize_t
+        * ssize_t.
         *
-        * Be careful here because iov_len is a size_t not an ssize_t
+        * In Linux, the total length is limited to MAX_RW_COUNT, there is
+        * no overflow possibility.
         */
        tot_len = 0;
        ret = -EINVAL;
        for (seg = 0; seg < nr_segs; seg++) {
-               compat_ssize_t tmp = tot_len;
                compat_uptr_t buf;
                compat_ssize_t len;
 
@@ -624,13 +625,13 @@ ssize_t compat_rw_copy_check_uvector(int type,
                }
                if (len < 0)    /* size_t not fitting in compat_ssize_t .. */
                        goto out;
-               tot_len += len;
-               if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
-                       goto out;
                if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
                        ret = -EFAULT;
                        goto out;
                }
+               if (len > MAX_RW_COUNT - tot_len)
+                       len = MAX_RW_COUNT - tot_len;
+               tot_len += len;
                iov->iov_base = compat_ptr(buf);
                iov->iov_len = (compat_size_t) len;
                uvector++;