summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorXinyu Zhang <xizhang@purestorage.com>2024-10-23 15:15:19 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-11-08 16:26:45 +0100
commit25326b9c135d765fb660310d1c5258ac1828d6b6 (patch)
treedda5cb8f531ed8b252deebc6d7463bc934819bdb /block
parent58c7f44c7b9e5ac7e3b1e5da2572ed7767a12f38 (diff)
downloadlinux-25326b9c135d765fb660310d1c5258ac1828d6b6.tar.gz
linux-25326b9c135d765fb660310d1c5258ac1828d6b6.tar.bz2
linux-25326b9c135d765fb660310d1c5258ac1828d6b6.zip
block: fix sanity checks in blk_rq_map_user_bvec
[ Upstream commit 2ff949441802a8d076d9013c7761f63e8ae5a9bd ] blk_rq_map_user_bvec contains a check bytes + bv->bv_len > nr_iter which causes unnecessary failures in NVMe passthrough I/O, reproducible as follows: - register a 2 page, page-aligned buffer against a ring - use that buffer to do a 1 page io_uring NVMe passthrough read The second (i = 1) iteration of the loop in blk_rq_map_user_bvec will then have nr_iter == 1 page, bytes == 1 page, bv->bv_len == 1 page, so the check bytes + bv->bv_len > nr_iter will succeed, causing the I/O to fail. This failure is unnecessary, as when the check succeeds, it means we've checked the entire buffer that will be used by the request - i.e. blk_rq_map_user_bvec should complete successfully. Therefore, terminate the loop early and return successfully when the check bytes + bv->bv_len > nr_iter succeeds. While we're at it, also remove the check that all segments in the bvec are single-page. While this seems to be true for all users of the function, it doesn't appear to be required anywhere downstream. CC: stable@vger.kernel.org Signed-off-by: Xinyu Zhang <xizhang@purestorage.com> Co-developed-by: Uday Shankar <ushankar@purestorage.com> Signed-off-by: Uday Shankar <ushankar@purestorage.com> Fixes: 37987547932c ("block: extend functionality to map bvec iterator") Link: https://lore.kernel.org/r/20241023211519.4177873-1-ushankar@purestorage.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'block')
-rw-r--r--block/blk-map.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/block/blk-map.c b/block/blk-map.c
index b337ae347bfa..a2fa38756037 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -597,9 +597,7 @@ static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len)
goto put_bio;
if (bytes + bv->bv_len > nr_iter)
- goto put_bio;
- if (bv->bv_offset + bv->bv_len > PAGE_SIZE)
- goto put_bio;
+ break;
nsegs++;
bytes += bv->bv_len;