57 lines
1.8 KiB
Diff
57 lines
1.8 KiB
Diff
From: Jens Axboe <jaxboe@fusionio.com>
|
|
Date: Wed, 10 Nov 2010 13:36:25 +0000 (+0100)
|
|
Subject: bio: take care not overflow page count when mapping/copying user data
|
|
X-Git-Tag: v2.6.37-rc4~22^2~14
|
|
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=cb4644cac4a2797afc847e6c92736664d4b0ea34
|
|
|
|
bio: take care not overflow page count when mapping/copying user data
|
|
|
|
If the iovec is being set up in a way that causes uaddr + PAGE_SIZE
|
|
to overflow, we could end up attempting to map a huge number of
|
|
pages. Check for this invalid input type.
|
|
|
|
Reported-by: Dan Rosenberg <drosenberg@vsecurity.com>
|
|
Cc: stable@kernel.org
|
|
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
|
|
---
|
|
|
|
diff --git a/fs/bio.c b/fs/bio.c
|
|
index 8317a2c..4bd454f 100644
|
|
--- a/fs/bio.c
|
|
+++ b/fs/bio.c
|
|
@@ -834,6 +834,12 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
|
|
end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
start = uaddr >> PAGE_SHIFT;
|
|
|
|
+ /*
|
|
+ * Overflow, abort
|
|
+ */
|
|
+ if (end < start)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
nr_pages += end - start;
|
|
len += iov[i].iov_len;
|
|
}
|
|
@@ -962,6 +968,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
|
|
unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
unsigned long start = uaddr >> PAGE_SHIFT;
|
|
|
|
+ /*
|
|
+ * Overflow, abort
|
|
+ */
|
|
+ if (end < start)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
nr_pages += end - start;
|
|
/*
|
|
* buffer must be aligned to at least hardsector size for now
|
|
@@ -989,7 +1001,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
|
|
unsigned long start = uaddr >> PAGE_SHIFT;
|
|
const int local_nr_pages = end - start;
|
|
const int page_limit = cur_page + local_nr_pages;
|
|
-
|
|
+
|
|
ret = get_user_pages_fast(uaddr, local_nr_pages,
|
|
write_to_vm, &pages[cur_page]);
|
|
if (ret < local_nr_pages) {
|