diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/compat.c b/fs/compat.c index 52cfeb61da77..ff66c0d7583d 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -606,14 +606,14 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
606 | /* | 606 | /* |
607 | * Single unix specification: | 607 | * Single unix specification: |
608 | * We should -EINVAL if an element length is not >= 0 and fitting an | 608 | * We should -EINVAL if an element length is not >= 0 and fitting an |
609 | * ssize_t. The total length is fitting an ssize_t | 609 | * ssize_t. |
610 | * | 610 | * |
611 | * Be careful here because iov_len is a size_t not an ssize_t | 611 | * In Linux, the total length is limited to MAX_RW_COUNT, there is |
612 | * no overflow possibility. | ||
612 | */ | 613 | */ |
613 | tot_len = 0; | 614 | tot_len = 0; |
614 | ret = -EINVAL; | 615 | ret = -EINVAL; |
615 | for (seg = 0; seg < nr_segs; seg++) { | 616 | for (seg = 0; seg < nr_segs; seg++) { |
616 | compat_ssize_t tmp = tot_len; | ||
617 | compat_uptr_t buf; | 617 | compat_uptr_t buf; |
618 | compat_ssize_t len; | 618 | compat_ssize_t len; |
619 | 619 | ||
@@ -624,13 +624,13 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
624 | } | 624 | } |
625 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ | 625 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ |
626 | goto out; | 626 | goto out; |
627 | tot_len += len; | ||
628 | if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ | ||
629 | goto out; | ||
630 | if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { | 627 | if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { |
631 | ret = -EFAULT; | 628 | ret = -EFAULT; |
632 | goto out; | 629 | goto out; |
633 | } | 630 | } |
631 | if (len > MAX_RW_COUNT - tot_len) | ||
632 | len = MAX_RW_COUNT - tot_len; | ||
633 | tot_len += len; | ||
634 | iov->iov_base = compat_ptr(buf); | 634 | iov->iov_base = compat_ptr(buf); |
635 | iov->iov_len = (compat_size_t) len; | 635 | iov->iov_len = (compat_size_t) len; |
636 | uvector++; | 636 | uvector++; |