]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.36.2/bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
1 From cb4644cac4a2797afc847e6c92736664d4b0ea34 Mon Sep 17 00:00:00 2001
2 From: Jens Axboe <jaxboe@fusionio.com>
3 Date: Wed, 10 Nov 2010 14:36:25 +0100
4 Subject: bio: take care not overflow page count when mapping/copying user data
5
6 From: Jens Axboe <jaxboe@fusionio.com>
7
8 commit cb4644cac4a2797afc847e6c92736664d4b0ea34 upstream.
9
10 If the iovec is being set up in a way that causes uaddr + PAGE_SIZE
11 to overflow, we could end up attempting to map a huge number of
12 pages. Check for this invalid input type.
13
14 Reported-by: Dan Rosenberg <drosenberg@vsecurity.com>
15 Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
16 Signed-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) {