aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma-buf/udmabuf.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 51cc585faab9..e32c381eca7d 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -12,6 +12,9 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/udmabuf.h> 13#include <linux/udmabuf.h>
14 14
15static const u32 list_limit = 1024; /* udmabuf_create_list->count limit */
16static const size_t size_limit_mb = 64; /* total dmabuf size, in megabytes */
17
15struct udmabuf { 18struct udmabuf {
16 pgoff_t pagecount; 19 pgoff_t pagecount;
17 struct page **pages; 20 struct page **pages;
@@ -123,7 +126,7 @@ static long udmabuf_create(const struct udmabuf_create_list *head,
123 struct file *memfd = NULL; 126 struct file *memfd = NULL;
124 struct udmabuf *ubuf; 127 struct udmabuf *ubuf;
125 struct dma_buf *buf; 128 struct dma_buf *buf;
126 pgoff_t pgoff, pgcnt, pgidx, pgbuf; 129 pgoff_t pgoff, pgcnt, pgidx, pgbuf, pglimit;
127 struct page *page; 130 struct page *page;
128 int seals, ret = -EINVAL; 131 int seals, ret = -EINVAL;
129 u32 i, flags; 132 u32 i, flags;
@@ -132,12 +135,15 @@ static long udmabuf_create(const struct udmabuf_create_list *head,
132 if (!ubuf) 135 if (!ubuf)
133 return -ENOMEM; 136 return -ENOMEM;
134 137
138 pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
135 for (i = 0; i < head->count; i++) { 139 for (i = 0; i < head->count; i++) {
136 if (!IS_ALIGNED(list[i].offset, PAGE_SIZE)) 140 if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
137 goto err_free_ubuf; 141 goto err_free_ubuf;
138 if (!IS_ALIGNED(list[i].size, PAGE_SIZE)) 142 if (!IS_ALIGNED(list[i].size, PAGE_SIZE))
139 goto err_free_ubuf; 143 goto err_free_ubuf;
140 ubuf->pagecount += list[i].size >> PAGE_SHIFT; 144 ubuf->pagecount += list[i].size >> PAGE_SHIFT;
145 if (ubuf->pagecount > pglimit)
146 goto err_free_ubuf;
141 } 147 }
142 ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(struct page *), 148 ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(struct page *),
143 GFP_KERNEL); 149 GFP_KERNEL);
@@ -227,7 +233,7 @@ static long udmabuf_ioctl_create_list(struct file *filp, unsigned long arg)
227 233
228 if (copy_from_user(&head, (void __user *)arg, sizeof(head))) 234 if (copy_from_user(&head, (void __user *)arg, sizeof(head)))
229 return -EFAULT; 235 return -EFAULT;
230 if (head.count > 1024) 236 if (head.count > list_limit)
231 return -EINVAL; 237 return -EINVAL;
232 lsize = sizeof(struct udmabuf_create_item) * head.count; 238 lsize = sizeof(struct udmabuf_create_item) * head.count;
233 list = memdup_user((void __user *)(arg + sizeof(head)), lsize); 239 list = memdup_user((void __user *)(arg + sizeof(head)), lsize);