summaryrefslogtreecommitdiffstats
path: root/lib/iov_iter.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-12-21 21:55:02 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-12-22 23:00:22 -0500
commit33844e665104b169a3a7732bdcddb40e4f82b335 (patch)
tree5432d8aeecc31c96696a19c56c0577d4499abdaa /lib/iov_iter.c
parentc00d2c7e89880036f288a764599b2b8b87c0a364 (diff)
[iov_iter] fix iterate_all_kinds() on empty iterators
Problem similar to ones dealt with in "fold checks into iterate_and_advance()" and followups, except that in this case we really want to do nothing when asked for zero-length operation - unlike zero-length iterate_and_advance(), zero-length iterate_all_kinds() has no side effects, and callers are simpler that way. That got exposed when copy_from_iter_full() had been used by tipc, which builds an msghdr with zero payload and (now) feeds it to a primitive based on iterate_all_kinds() instead of iterate_and_advance(). Reported-by: Jon Maloy <jon.maloy@ericsson.com> Tested-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r--lib/iov_iter.c55
1 files changed, 26 insertions, 29 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 228892dabba6..25f572303801 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -73,19 +73,21 @@
73} 73}
74 74
75#define iterate_all_kinds(i, n, v, I, B, K) { \ 75#define iterate_all_kinds(i, n, v, I, B, K) { \
76 size_t skip = i->iov_offset; \ 76 if (likely(n)) { \
77 if (unlikely(i->type & ITER_BVEC)) { \ 77 size_t skip = i->iov_offset; \
78 struct bio_vec v; \ 78 if (unlikely(i->type & ITER_BVEC)) { \
79 struct bvec_iter __bi; \ 79 struct bio_vec v; \
80 iterate_bvec(i, n, v, __bi, skip, (B)) \ 80 struct bvec_iter __bi; \
81 } else if (unlikely(i->type & ITER_KVEC)) { \ 81 iterate_bvec(i, n, v, __bi, skip, (B)) \
82 const struct kvec *kvec; \ 82 } else if (unlikely(i->type & ITER_KVEC)) { \
83 struct kvec v; \ 83 const struct kvec *kvec; \
84 iterate_kvec(i, n, v, kvec, skip, (K)) \ 84 struct kvec v; \
85 } else { \ 85 iterate_kvec(i, n, v, kvec, skip, (K)) \
86 const struct iovec *iov; \ 86 } else { \
87 struct iovec v; \ 87 const struct iovec *iov; \
88 iterate_iovec(i, n, v, iov, skip, (I)) \ 88 struct iovec v; \
89 iterate_iovec(i, n, v, iov, skip, (I)) \
90 } \
89 } \ 91 } \
90} 92}
91 93
@@ -576,7 +578,7 @@ bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
576 WARN_ON(1); 578 WARN_ON(1);
577 return false; 579 return false;
578 } 580 }
579 if (unlikely(i->count < bytes)) \ 581 if (unlikely(i->count < bytes))
580 return false; 582 return false;
581 583
582 iterate_all_kinds(i, bytes, v, ({ 584 iterate_all_kinds(i, bytes, v, ({
@@ -620,7 +622,7 @@ bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i)
620 WARN_ON(1); 622 WARN_ON(1);
621 return false; 623 return false;
622 } 624 }
623 if (unlikely(i->count < bytes)) \ 625 if (unlikely(i->count < bytes))
624 return false; 626 return false;
625 iterate_all_kinds(i, bytes, v, ({ 627 iterate_all_kinds(i, bytes, v, ({
626 if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len, 628 if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len,
@@ -837,11 +839,8 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
837 unsigned long res = 0; 839 unsigned long res = 0;
838 size_t size = i->count; 840 size_t size = i->count;
839 841
840 if (!size)
841 return 0;
842
843 if (unlikely(i->type & ITER_PIPE)) { 842 if (unlikely(i->type & ITER_PIPE)) {
844 if (i->iov_offset && allocated(&i->pipe->bufs[i->idx])) 843 if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx]))
845 return size | i->iov_offset; 844 return size | i->iov_offset;
846 return size; 845 return size;
847 } 846 }
@@ -856,10 +855,8 @@ EXPORT_SYMBOL(iov_iter_alignment);
856 855
857unsigned long iov_iter_gap_alignment(const struct iov_iter *i) 856unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
858{ 857{
859 unsigned long res = 0; 858 unsigned long res = 0;
860 size_t size = i->count; 859 size_t size = i->count;
861 if (!size)
862 return 0;
863 860
864 if (unlikely(i->type & ITER_PIPE)) { 861 if (unlikely(i->type & ITER_PIPE)) {
865 WARN_ON(1); 862 WARN_ON(1);
@@ -874,7 +871,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
874 (res |= (!res ? 0 : (unsigned long)v.iov_base) | 871 (res |= (!res ? 0 : (unsigned long)v.iov_base) |
875 (size != v.iov_len ? size : 0)) 872 (size != v.iov_len ? size : 0))
876 ); 873 );
877 return res; 874 return res;
878} 875}
879EXPORT_SYMBOL(iov_iter_gap_alignment); 876EXPORT_SYMBOL(iov_iter_gap_alignment);
880 877
@@ -908,6 +905,9 @@ static ssize_t pipe_get_pages(struct iov_iter *i,
908 size_t capacity; 905 size_t capacity;
909 int idx; 906 int idx;
910 907
908 if (!maxsize)
909 return 0;
910
911 if (!sanity(i)) 911 if (!sanity(i))
912 return -EFAULT; 912 return -EFAULT;
913 913
@@ -926,9 +926,6 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
926 if (maxsize > i->count) 926 if (maxsize > i->count)
927 maxsize = i->count; 927 maxsize = i->count;
928 928
929 if (!maxsize)
930 return 0;
931
932 if (unlikely(i->type & ITER_PIPE)) 929 if (unlikely(i->type & ITER_PIPE))
933 return pipe_get_pages(i, pages, maxsize, maxpages, start); 930 return pipe_get_pages(i, pages, maxsize, maxpages, start);
934 iterate_all_kinds(i, maxsize, v, ({ 931 iterate_all_kinds(i, maxsize, v, ({
@@ -975,6 +972,9 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
975 int idx; 972 int idx;
976 int npages; 973 int npages;
977 974
975 if (!maxsize)
976 return 0;
977
978 if (!sanity(i)) 978 if (!sanity(i))
979 return -EFAULT; 979 return -EFAULT;
980 980
@@ -1006,9 +1006,6 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
1006 if (maxsize > i->count) 1006 if (maxsize > i->count)
1007 maxsize = i->count; 1007 maxsize = i->count;
1008 1008
1009 if (!maxsize)
1010 return 0;
1011
1012 if (unlikely(i->type & ITER_PIPE)) 1009 if (unlikely(i->type & ITER_PIPE))
1013 return pipe_get_pages_alloc(i, pages, maxsize, start); 1010 return pipe_get_pages_alloc(i, pages, maxsize, start);
1014 iterate_all_kinds(i, maxsize, v, ({ 1011 iterate_all_kinds(i, maxsize, v, ({