summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSri Krishna chowdary <schowdary@nvidia.com>2016-12-14 11:58:30 +0530
committerWinnie Hsu <whsu@nvidia.com>2017-06-09 11:19:54 -0700
commitb4328544835de3fc8215f37668dc97fc21013136 (patch)
tree774c63add5582421ff85f319088d20f88ea87888
parent642ec539ddab846143db87673ace653d09c75e05 (diff)
video: tegra: nvmap: Fix NULL pointer dereference
Consider the following case: 1. NVMAP_IOC_CREATE on IOVMM gives a valid fd to user space 2. user space does not call NVMAP_IOC_ALLOC. 3. user space calls a client driver IOCTL which calls dma_buf_map_attachment 4. call to dma_buf_map_attachment propagates till__nvmap_sg_table which has heap_pgalloc as true and tries to access pages[] which has all NULL. 5. Similarly, a dma_buf_kmap() can result in __nvmap_kmap() being called which again results in NULL dereference if pages[] is accessed. A valid __nvmap_sg_table should occur only when h->alloc is true. So, add check for it. bug 1838597 bug 1883708 Change-Id: I400d9d8a94ff1003db207fc9c252b9256d796f60 Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com> Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> (cherry picked from commit 8244d104b7635cb0b26b651b6851498b9a84d7d6) Reviewed-on: http://git-master/r/1489579 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu <bbasu@nvidia.com> Tested-by: Bibek Basu <bbasu@nvidia.com>
-rw-r--r--drivers/video/tegra/nvmap/nvmap.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c
index 09f436102c6b..662646a2d6c6 100644
--- a/drivers/video/tegra/nvmap/nvmap.c
+++ b/drivers/video/tegra/nvmap/nvmap.c
@@ -3,7 +3,7 @@
*
* Memory manager for Tegra GPU
*
- * Copyright (c) 2009-2014, 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
@@ -196,6 +196,9 @@ void *__nvmap_kmap(struct nvmap_handle *h, unsigned int pagenum)
if (!h)
return NULL;
+ if (!h->alloc)
+ goto out;
+
if (pagenum >= h->size >> PAGE_SHIFT)
goto out;
prot = nvmap_pgprot(h, PG_PROT_KERNEL);
@@ -222,7 +225,7 @@ void __nvmap_kunmap(struct nvmap_handle *h, unsigned int pagenum,
phys_addr_t paddr;
struct vm_struct *area = NULL;
- if (!h ||
+ if (!h || !h->alloc ||
WARN_ON(!virt_addr_valid(h)) ||
WARN_ON(!addr))
return;
@@ -266,7 +269,7 @@ void *__nvmap_mmap(struct nvmap_handle *h)
return NULL;
if (!h->alloc)
- return NULL;
+ goto put_handle;
prot = nvmap_pgprot(h, PG_PROT_KERNEL);
@@ -276,7 +279,7 @@ void *__nvmap_mmap(struct nvmap_handle *h)
pages = nvmap_pages(h->pgalloc.pages,
h->size >> PAGE_SHIFT);
if (!pages)
- return NULL;
+ goto put_handle;
vaddr = vm_map_ram(pages,
h->size >> PAGE_SHIFT, -1, prot);
nvmap_altfree(pages,
@@ -296,10 +299,8 @@ void *__nvmap_mmap(struct nvmap_handle *h)
adj_size = PAGE_ALIGN(adj_size);
v = alloc_vm_area(adj_size, 0);
- if (!v) {
- nvmap_handle_put(h);
- return NULL;
- }
+ if (!v)
+ goto put_handle;
p = v->addr + (h->carveout->base & ~PAGE_MASK);
ioremap_page_range((ulong)v->addr, (ulong)v->addr + adj_size,
@@ -309,11 +310,14 @@ void *__nvmap_mmap(struct nvmap_handle *h)
* the handle will not be freed while the kernel mapping exists.
* nvmap_handle_put will be called by unmapping this address */
return p;
+put_handle:
+ nvmap_handle_put(h);
+ return NULL;
}
void __nvmap_munmap(struct nvmap_handle *h, void *addr)
{
- if (!h ||
+ if (!h || !h->alloc ||
WARN_ON(!virt_addr_valid(h)) ||
WARN_ON(!addr))
return;
@@ -447,6 +451,11 @@ struct sg_table *__nvmap_sg_table(struct nvmap_client *client,
if (!h)
return ERR_PTR(-EINVAL);
+ if (!h->alloc) {
+ err = -EINVAL;
+ goto put_handle;
+ }
+
npages = PAGE_ALIGN(h->size) >> PAGE_SHIFT;
sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
if (!sgt) {
@@ -476,6 +485,7 @@ struct sg_table *__nvmap_sg_table(struct nvmap_client *client,
err:
kfree(sgt);
+put_handle:
nvmap_handle_put(h);
return ERR_PTR(err);
}