Message ID | 20210827164926.1726765-2-agruenba@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | gfs2: Fix mmap + page fault deadlocks | expand |
On Fri, Aug 27, 2021 at 06:49:08PM +0200, Andreas Gruenbacher wrote: > Both iov_iter_get_pages and iov_iter_get_pages_alloc return the number > of bytes of the iovec they could get the pages for. When they cannot > get any pages, they're supposed to return 0, but when the start of the > iovec isn't page aligned, the calculation goes wrong and they return a > negative value. Fix both functions. > > In addition, change iov_iter_get_pages_alloc to return NULL in that case > to prevent resource leaks. > > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de>
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index e23123ae3a13..25dfc48536d7 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1484,7 +1484,7 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE ? FOLL_WRITE : 0, pages); - if (unlikely(res < 0)) + if (unlikely(res <= 0)) return res; return (res == n ? len : res * PAGE_SIZE) - *start; } @@ -1608,8 +1608,9 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, return -ENOMEM; res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE ? FOLL_WRITE : 0, p); - if (unlikely(res < 0)) { + if (unlikely(res <= 0)) { kvfree(p); + *pages = NULL; return res; } *pages = p;
Both iov_iter_get_pages and iov_iter_get_pages_alloc return the number of bytes of the iovec they could get the pages for. When they cannot get any pages, they're supposed to return 0, but when the start of the iovec isn't page aligned, the calculation goes wrong and they return a negative value. Fix both functions. In addition, change iov_iter_get_pages_alloc to return NULL in that case to prevent resource leaks. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- lib/iov_iter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)