]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mm/filemap: fix infinite loop in generic_file_buffered_read()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 18 Dec 2020 09:07:11 +0000 (04:07 -0500)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Dec 2020 21:37:04 +0000 (13:37 -0800)
If iter->count is 0 and iocb->ki_pos is page aligned, this causes
nr_pages to be 0.

Then in generic_file_buffered_read_get_pages() find_get_pages_contig()
returns 0 - because we asked for 0 pages, so we call
generic_file_buffered_read_no_cached_page() which attempts to add a page
to the page cache, which fails with -EEXIST, and then we loop. Oops...

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Reported-by: Jens Axboe <axboe@kernel.dk>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/filemap.c

index 7a49bac48aea559a17be7b4c0d77c82391d9ac27..5c9d564317a5c5eb2e7f5c4edc6e5e3571bd9c2d 100644 (file)
@@ -2453,6 +2453,9 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
 
        if (unlikely(iocb->ki_pos >= inode->i_sb->s_maxbytes))
                return 0;
+       if (unlikely(!iov_iter_count(iter)))
+               return 0;
+
        iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
 
        if (nr_pages > ARRAY_SIZE(pages_onstack))