diff options
author | Tuomas Tynkkynen <ttynkkynen@nvidia.com> | 2012-07-30 12:40:45 +0300 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-07-31 14:59:00 -0700 |
commit | afb5a244504ac8535aa80781f0faf4d629d6dc32 (patch) | |
tree | 15eedd3f9790e5ca340bd1965fc860c2741993a7 /drivers/video | |
parent | 524a9932de822961cd6fda49560af637bf8e9722 (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')
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_ioctl.c | 6 |
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; } |