summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2019-07-01 15:14:46 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-14 08:01:08 +0200
commitc785529bebceeaf38db8ebf9b50ff3a173fb18c6 (patch)
tree592117f52a65756df77dcd99ebc14f20dafda815 /fs
parenta6d278658745fa72fe810394759f9f786993cd33 (diff)
downloadlinux-stable-c785529bebceeaf38db8ebf9b50ff3a173fb18c6.tar.gz
linux-stable-c785529bebceeaf38db8ebf9b50ff3a173fb18c6.tar.bz2
linux-stable-c785529bebceeaf38db8ebf9b50ff3a173fb18c6.zip
block: fix .bi_size overflow
commit 79d08f89bb1b5c2c1ff90d9bb95497ab9e8aa7e0 upstream. 'bio->bi_iter.bi_size' is 'unsigned int', which at most hold 4G - 1 bytes. Before 07173c3ec276 ("block: enable multipage bvecs"), one bio can include very limited pages, and usually at most 256, so the fs bio size won't be bigger than 1M bytes most of times. Since we support multi-page bvec, in theory one fs bio really can be added > 1M pages, especially in case of hugepage, or big writeback with too many dirty pages. Then there is chance in which .bi_size is overflowed. Fixes this issue by using bio_full() to check if the added segment may overflow .bi_size. Cc: Liu Yiding <liuyd.fnst@cn.fujitsu.com> Cc: kernel test robot <rong.a.chen@intel.com> Cc: "Darrick J. Wong" <darrick.wong@oracle.com> Cc: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 07173c3ec276 ("block: enable multipage bvecs") Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/iomap.c2
-rw-r--r--fs/xfs/xfs_aops.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/fs/iomap.c b/fs/iomap.c
index 12654c2e78f8..da961fca3180 100644
--- a/fs/iomap.c
+++ b/fs/iomap.c
@@ -333,7 +333,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
if (iop)
atomic_inc(&iop->read_count);
- if (!ctx->bio || !is_contig || bio_full(ctx->bio)) {
+ if (!ctx->bio || !is_contig || bio_full(ctx->bio, plen)) {
gfp_t gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL);
int nr_vecs = (length + PAGE_SIZE - 1) >> PAGE_SHIFT;
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 8da5e6637771..11f703d4a605 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -782,7 +782,7 @@ xfs_add_to_ioend(
atomic_inc(&iop->write_count);
if (!merged) {
- if (bio_full(wpc->ioend->io_bio))
+ if (bio_full(wpc->ioend->io_bio, len))
xfs_chain_bio(wpc->ioend, wbc, bdev, sector);
bio_add_page(wpc->ioend->io_bio, page, len, poff);
}