summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap
diff options
context:
space:
mode:
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>2012-07-30 12:40:45 +0300
committerSimone Willett <swillett@nvidia.com>2012-07-31 14:59:00 -0700
commitafb5a244504ac8535aa80781f0faf4d629d6dc32 (patch)
tree15eedd3f9790e5ca340bd1965fc860c2741993a7 /drivers/video/tegra/nvmap
parent524a9932de822961cd6fda49560af637bf8e9722 (diff)
video: tegra: nvmap: Fix two integer overflows.
nvmap_ioctl_pinop kmalloc's a temporary buffer, whose length is directly given by ioctl parameter from usermode. The total size of the buffer is not checked for overflow, which will cause a kernel panic with some inputs. Also, a sizeof() is applied to wrong type when calculating the amount of bytes to copy from userspace. nvmap_map_into_caller_ptr attempts to validate that the memory range to be mapped is correct, but integer overflow can cause the check to fail. This will lead to mapping wrong pages from the allocated handle later on, when the page fault handler gets called. Bug 1025502 Change-Id: I71a09c40c209dba9c5b37c3912e92a81e6f87e80 Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/nvmap')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c
index 44f00d2951a0..5bfbbf60f8ff 100644
--- a/drivers/video/tegra/nvmap/nvmap_ioctl.c
+++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c
@@ -65,10 +65,10 @@ int nvmap_ioctl_pinop(struct file *filp, bool is_pin, void __user *arg)
return -EINVAL;
if (op.count > 1) {
- size_t bytes = op.count * sizeof(unsigned long *);
+ size_t bytes = op.count * sizeof(*refs); /* kcalloc below will catch overflow. */
if (op.count > ARRAY_SIZE(on_stack))
- refs = kmalloc(op.count * sizeof(*refs), GFP_KERNEL);
+ refs = kcalloc(op.count, sizeof(*refs), GFP_KERNEL);
else
refs = on_stack;
@@ -251,7 +251,7 @@ int nvmap_map_into_caller_ptr(struct file *filp, void __user *arg)
goto out;
}
- if ((op.offset + op.length) > h->size) {
+ if (op.offset > h->size || (op.offset + op.length) > h->size) {
err = -EADDRNOTAVAIL;
goto out;
}