Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95d78c28 authored by Vitaly Mayatskikh's avatar Vitaly Mayatskikh Committed by Al Viro
Browse files

fix unbalanced page refcounting in bio_map_user_iov



bio_map_user_iov and bio_unmap_user do unbalanced pages refcounting if
IO vector has small consecutive buffers belonging to the same page.
bio_add_pc_page merges them into one, but the page reference is never
dropped.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarVitaly Mayatskikh <v.mayatskih@gmail.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 899f0429
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -1383,6 +1383,7 @@ struct bio *bio_map_user_iov(struct request_queue *q,
		offset = offset_in_page(uaddr);
		offset = offset_in_page(uaddr);
		for (j = cur_page; j < page_limit; j++) {
		for (j = cur_page; j < page_limit; j++) {
			unsigned int bytes = PAGE_SIZE - offset;
			unsigned int bytes = PAGE_SIZE - offset;
			unsigned short prev_bi_vcnt = bio->bi_vcnt;


			if (len <= 0)
			if (len <= 0)
				break;
				break;
@@ -1397,6 +1398,13 @@ struct bio *bio_map_user_iov(struct request_queue *q,
					    bytes)
					    bytes)
				break;
				break;


			/*
			 * check if vector was merged with previous
			 * drop page reference if needed
			 */
			if (bio->bi_vcnt == prev_bi_vcnt)
				put_page(pages[j]);

			len -= bytes;
			len -= bytes;
			offset = 0;
			offset = 0;
		}
		}