In bio_map_user_iov(), when iov_iter_extract_pages() is called with pages set to NULL (because nr_vecs > UIO_FASTIOV), want_pages_array() internally allocates a pages array via kvmalloc_array(). If iov_iter_extract_pages() subsequently returns bytes <= 0 (e.g., due to pin_user_pages_fast() failure), the code jumps to out_unmap without freeing the dynamically allocated pages array, causing a memory leak detectable by kmemleak. This can be triggered from userspace by issuing an SG_IO v4 ioctl on a bsg device with a large din_xfer_len and an invalid din_xferp (mapped PROT_NONE), which causes pin_user_pages_fast() to fail after the pages array has already been allocated by want_pages_array(). The kmemleak backtrace looks like: unreferenced object 0xffff... (size 2048): backtrace (crc 0): kvmalloc_node+0x... want_pages_array+0x... iov_iter_extract_pages+0x... bio_map_user_iov+0x... blk_rq_map_user_iov+0x... blk_rq_map_user+0x... bsg_transport_sg_io_fn+0x... Fix this by freeing the dynamically allocated pages array (when it differs from the on-stack stack_pages) before jumping to the error path. Fixes: 403b6fb8dac1 ("block: convert bio_map_user_iov to use iov_iter_extract_pages") Cc: stable@vger.kernel.org # 6.5+ Signed-off-by: Xin Yin --- block/blk-map.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/blk-map.c b/block/blk-map.c index 0aadbaf7a9ddd..5b9f14caad4f9 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -304,6 +304,8 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, bytes = iov_iter_extract_pages(iter, &pages, LONG_MAX, nr_vecs, extraction_flags, &offs); if (unlikely(bytes <= 0)) { + if (pages != stack_pages) + kvfree(pages); ret = bytes ? bytes : -EFAULT; goto out_unmap; } -- 2.20.1