summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorSri Krishna chowdary <schowdary@nvidia.com>2017-02-10 15:02:14 +0530
committerWinnie Hsu <whsu@nvidia.com>2017-03-20 13:08:09 -0700
commitfe2aed5a0d1b353f723d9e4dc6669dfa63b64e0a (patch)
tree0ccd0d58ed42648fa88f762fa84da9acd2c35a44 /drivers/video
parentf01956fc2151561a7845ebdb8f836ad4851af69e (diff)
video: tegra: nvmap: fix time-of-check,time-of-use vulnerability
Validate the region specified by offset and size before performing the operations like nvmap_prot_handle, nvmap_cache_maint and nvmap_handle_mk*. This validation of offset and size once the values are in local variables guarantees that even though user space changes the values in user buffers, nvmap continues to perform operations with the contents that are validated. Fixes Google Bug 34113000. bug 1862379 Change-Id: Ief81887b3d94b49f3dcf4d2680d9d7b257c54092 Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com> Signed-off-by: Bibek Basu <bbasu@nvidia.com> Reviewed-on: http://git-master/r/1298712 (cherry picked from commit f45441da608d8015ece73d253d4bdb48863f99e2) Reviewed-on: http://git-master/r/1310316 (cherry picked from commit 57367ab3be5f1c52dd6b885f114ae90dfce5a363) Reviewed-on: http://git-master/r/1319910 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.c9
-rw-r--r--drivers/video/tegra/nvmap/nvmap_mm.c6
-rw-r--r--drivers/video/tegra/nvmap/nvmap_priv.h11
3 files changed, 19 insertions, 7 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c
index 850afd1ff437..7e59d245069f 100644
--- a/drivers/video/tegra/nvmap/nvmap_ioctl.c
+++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c
@@ -3,7 +3,7 @@
*
* User-space interface to nvmap
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -936,6 +936,11 @@ int __nvmap_do_cache_maint(struct nvmap_client *client,
if (!h)
return -EFAULT;
+ if ((start >= h->size) || (end > h->size)) {
+ nvmap_handle_put(h);
+ return -EFAULT;
+ }
+
if (op == NVMAP_CACHE_OP_INV)
op = NVMAP_CACHE_OP_WB_INV;
@@ -1088,7 +1093,7 @@ int nvmap_ioctl_cache_maint_list(struct file *filp, void __user *arg,
if (copy_from_user(&op, arg, sizeof(op)))
return -EFAULT;
- if (!op.nr)
+ if (!op.nr || op.nr > UINT_MAX / sizeof(u32))
return -EINVAL;
if (!access_ok(VERIFY_READ, op.handles, op.nr * sizeof(u32)))
diff --git a/drivers/video/tegra/nvmap/nvmap_mm.c b/drivers/video/tegra/nvmap/nvmap_mm.c
index 133f00b1aaa9..30994e681121 100644
--- a/drivers/video/tegra/nvmap/nvmap_mm.c
+++ b/drivers/video/tegra/nvmap/nvmap_mm.c
@@ -3,7 +3,7 @@
*
* Some MM related functionality specific to nvmap.
*
- * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -193,6 +193,10 @@ void nvmap_zap_handle(struct nvmap_handle *handle, u32 offset, u32 size)
size = PAGE_ALIGN((offset & ~PAGE_MASK) + size);
+ if ((offset >= handle->size) || (offset > handle->size - size) ||
+ (size > handle->size))
+ return;
+
mutex_lock(&handle->lock);
vmas = &handle->vmas;
list_for_each_entry(vma_list, vmas, list) {
diff --git a/drivers/video/tegra/nvmap/nvmap_priv.h b/drivers/video/tegra/nvmap/nvmap_priv.h
index a90a3269cd62..705745702abd 100644
--- a/drivers/video/tegra/nvmap/nvmap_priv.h
+++ b/drivers/video/tegra/nvmap/nvmap_priv.h
@@ -3,7 +3,7 @@
*
* GPU memory management driver for Tegra
*
- * Copyright (c) 2009-2016, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -467,10 +467,13 @@ static inline void nvmap_handle_mk(struct nvmap_handle *h,
void (*fn)(struct page **))
{
int i;
- int start_page = PAGE_ALIGN(offset) >> PAGE_SHIFT;
- int end_page = (offset + size) >> PAGE_SHIFT;
+ u32 start_page = offset >> PAGE_SHIFT;
+ u32 end_page = PAGE_ALIGN(offset + size) >> PAGE_SHIFT;
- if (h->heap_pgalloc) {
+ if (h->heap_pgalloc &&
+ (offset < h->size) &&
+ (size <= h->size) &&
+ (offset <= (h->size - size))) {
for (i = start_page; i < end_page; i++)
fn(&h->pgalloc.pages[i]);
}