mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
video: tegra: nvmap: Add checks for addition overflow
Add check for overflow when two unsigned integers are added and return error in case of overflow condition. CID 13772217 CID 13772356 CID 13772469 CID 13772634 CID 13772882 CID 13772995 JIRA: TMM-5724 Bug 4479044 Change-Id: Iaa04cc45bfe11a0cfb2e8124d9423e3a66e39f73 Signed-off-by: Surbhi Singh <surbhis@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3270465 Reviewed-by: Ajay Nandakumar Mannargudi <anandakumarm@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2009-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
* SPDX-FileCopyrightText: Copyright (c) 2009-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* Memory manager for Tegra GPU
|
* Memory manager for Tegra GPU
|
||||||
*/
|
*/
|
||||||
@@ -96,7 +96,9 @@ void *__nvmap_mmap(struct nvmap_handle *h)
|
|||||||
|
|
||||||
/* carveout - explicitly map the pfns into a vmalloc area */
|
/* carveout - explicitly map the pfns into a vmalloc area */
|
||||||
adj_size = nvmap_get_heap_block_base(h->carveout) & ~PAGE_MASK;
|
adj_size = nvmap_get_heap_block_base(h->carveout) & ~PAGE_MASK;
|
||||||
adj_size += h->size;
|
if (check_add_overflow(adj_size, h->size, &adj_size))
|
||||||
|
goto dec_kmaps;
|
||||||
|
|
||||||
adj_size = PAGE_ALIGN(adj_size);
|
adj_size = PAGE_ALIGN(adj_size);
|
||||||
|
|
||||||
if (pfn_valid(__phys_to_pfn(nvmap_get_heap_block_base(h->carveout) & PAGE_MASK))) {
|
if (pfn_valid(__phys_to_pfn(nvmap_get_heap_block_base(h->carveout) & PAGE_MASK))) {
|
||||||
@@ -149,6 +151,7 @@ void *__nvmap_mmap(struct nvmap_handle *h)
|
|||||||
out:
|
out:
|
||||||
if (pages)
|
if (pages)
|
||||||
vfree(pages);
|
vfree(pages);
|
||||||
|
dec_kmaps:
|
||||||
nvmap_kmaps_dec(h);
|
nvmap_kmaps_dec(h);
|
||||||
put_handle:
|
put_handle:
|
||||||
nvmap_handle_put(h);
|
nvmap_handle_put(h);
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ static int nvmap_page_mapcount(struct page *page)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define PSS_SHIFT 12
|
#define PSS_SHIFT 12
|
||||||
static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id)
|
static int nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct rb_node *n;
|
struct rb_node *n;
|
||||||
@@ -307,7 +307,7 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id
|
|||||||
if (pss)
|
if (pss)
|
||||||
*pss = 0;
|
*pss = 0;
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return;
|
return 0;
|
||||||
spin_lock(&dev->handle_lock);
|
spin_lock(&dev->handle_lock);
|
||||||
n = rb_first(&dev->handles);
|
n = rb_first(&dev->handles);
|
||||||
for (; n != NULL; n = rb_next(n)) {
|
for (; n != NULL; n = rb_next(n)) {
|
||||||
@@ -322,18 +322,28 @@ static void nvmap_get_total_mss(u64 *pss, u64 *total, u32 heap_type, int numa_id
|
|||||||
numa_id))
|
numa_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*total += h->size;
|
if (check_add_overflow(*total, (u64)h->size, &*total)) {
|
||||||
|
spin_unlock(&dev->handle_lock);
|
||||||
|
return -EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pss)
|
if (!pss)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = 0; i < h->size >> PAGE_SHIFT; i++) {
|
for (i = 0; i < h->size >> PAGE_SHIFT; i++) {
|
||||||
struct page *page = nvmap_to_page(h->pgalloc.pages[i]);
|
struct page *page = nvmap_to_page(h->pgalloc.pages[i]);
|
||||||
|
|
||||||
if (nvmap_page_mapcount(page) > 0)
|
if (nvmap_page_mapcount(page) > 0) {
|
||||||
*pss += PAGE_SIZE;
|
if (check_add_overflow(*pss, (u64)PAGE_SIZE, &*pss)) {
|
||||||
|
spin_unlock(&dev->handle_lock);
|
||||||
|
return -EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&dev->handle_lock);
|
spin_unlock(&dev->handle_lock);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nvmap_debug_allocations_show(struct seq_file *s, void *unused)
|
static int nvmap_debug_allocations_show(struct seq_file *s, void *unused)
|
||||||
@@ -365,7 +375,10 @@ static int nvmap_debug_allocations_show(struct seq_file *s, void *unused)
|
|||||||
seq_puts(s, "\n");
|
seq_puts(s, "\n");
|
||||||
}
|
}
|
||||||
mutex_unlock(&nvmap_dev->clients_lock);
|
mutex_unlock(&nvmap_dev->clients_lock);
|
||||||
nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total));
|
seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -581,7 +594,10 @@ static int nvmap_debug_maps_show(struct seq_file *s, void *unused)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&nvmap_dev->clients_lock);
|
mutex_unlock(&nvmap_dev->clients_lock);
|
||||||
|
|
||||||
nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total));
|
seq_printf(s, "%-18s %-18s %8s %10lluK\n", "total", "", "", K(total));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -612,7 +628,10 @@ static int nvmap_debug_clients_show(struct seq_file *s, void *unused)
|
|||||||
seq_printf(s, " %10lluK\n", K(client_total));
|
seq_printf(s, " %10lluK\n", K(client_total));
|
||||||
}
|
}
|
||||||
mutex_unlock(&nvmap_dev->clients_lock);
|
mutex_unlock(&nvmap_dev->clients_lock);
|
||||||
nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
err = nvmap_get_total_mss(NULL, &total, heap_type, numa_id);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
seq_printf(s, "%-18s %18s %8s %10lluK\n", "total", "", "", K(total));
|
seq_printf(s, "%-18s %18s %8s %10lluK\n", "total", "", "", K(total));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -833,7 +852,10 @@ static int nvmap_debug_iovmm_procrank_show(struct seq_file *s, void *unused)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&dev->clients_lock);
|
mutex_unlock(&dev->clients_lock);
|
||||||
|
|
||||||
nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM, NUMA_NO_NODE);
|
err = nvmap_get_total_mss(&total_pss, &total_memory, NVMAP_HEAP_IOVMM, NUMA_NO_NODE);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
seq_printf(s, "%-18s %18s %8s %10lluK %10lluK\n",
|
seq_printf(s, "%-18s %18s %8s %10lluK %10lluK\n",
|
||||||
"total", "", "", K(total_pss), K(total_memory));
|
"total", "", "", K(total_pss), K(total_memory));
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user