]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.2/bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
CommitLineData
d86d85d9
GKH
1From cb4644cac4a2797afc847e6c92736664d4b0ea34 Mon Sep 17 00:00:00 2001
2From: Jens Axboe <jaxboe@fusionio.com>
3Date: Wed, 10 Nov 2010 14:36:25 +0100
4Subject: bio: take care not overflow page count when mapping/copying user data
5
6From: Jens Axboe <jaxboe@fusionio.com>
7
8commit cb4644cac4a2797afc847e6c92736664d4b0ea34 upstream.
9
10If the iovec is being set up in a way that causes uaddr + PAGE_SIZE
11to overflow, we could end up attempting to map a huge number of
12pages. Check for this invalid input type.
13
14Reported-by: Dan Rosenberg <drosenberg@vsecurity.com>
15Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
16Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
17
18---
19 fs/bio.c | 14 +++++++++++++-
20 1 file changed, 13 insertions(+), 1 deletion(-)
21
22--- a/fs/bio.c
23+++ b/fs/bio.c
24@@ -834,6 +834,12 @@ struct bio *bio_copy_user_iov(struct req
25 end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
26 start = uaddr >> PAGE_SHIFT;
27
28+ /*
29+ * Overflow, abort
30+ */
31+ if (end < start)
32+ return ERR_PTR(-EINVAL);
33+
34 nr_pages += end - start;
35 len += iov[i].iov_len;
36 }
37@@ -962,6 +968,12 @@ static struct bio *__bio_map_user_iov(st
38 unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
39 unsigned long start = uaddr >> PAGE_SHIFT;
40
41+ /*
42+ * Overflow, abort
43+ */
44+ if (end < start)
45+ return ERR_PTR(-EINVAL);
46+
47 nr_pages += end - start;
48 /*
49 * buffer must be aligned to at least hardsector size for now
50@@ -989,7 +1001,7 @@ static struct bio *__bio_map_user_iov(st
51 unsigned long start = uaddr >> PAGE_SHIFT;
52 const int local_nr_pages = end - start;
53 const int page_limit = cur_page + local_nr_pages;
54-
55+
56 ret = get_user_pages_fast(uaddr, local_nr_pages,
57 write_to_vm, &pages[cur_page]);
58 if (ret < local_nr_pages) {