video: tegra: nvmap: Add checks for addition overflow

Add check for overflow when two unsigned integers are added or
multiplied and return error in case of overflow condition.

JIRA TMM-5993
Bug 4479044

Change-Id: I79233e276d85570e63e8b36fd1dd4778a174c69d
Signed-off-by: Surbhi Singh <surbhis@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3306728
Reviewed-by: Ketan Patil <ketanp@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
This commit is contained in:
Surbhi Singh
2025-02-20 09:13:57 +00:00
committed by Jon Hunter
parent 053dc08de7
commit 6173caca37

View File

@@ -75,6 +75,9 @@ void nvmap_clean_cache(struct page **pages, int numpages)
sizeof(*td_array)); sizeof(*td_array));
int created_threads = 0, j; int created_threads = 0, j;
size_t set_size, last_set_size; size_t set_size, last_set_size;
size_t sub_total_pages;
size_t rem_pages;
size_t temp;
if (!td_array) { if (!td_array) {
pr_err("td_array allocation failed\n"); pr_err("td_array allocation failed\n");
@@ -95,8 +98,18 @@ void nvmap_clean_cache(struct page **pages, int numpages)
* pages, as numpages may not be always divisible by * pages, as numpages may not be always divisible by
* number of online_cpus. * number of online_cpus.
*/ */
last_set_size = (unsigned long long) (numpages - (set_size if (check_mul_overflow(set_size, (size_t)(online_cpus - 1), &sub_total_pages)) {
* (online_cpus - 1))) << PAGE_SHIFT; vunmap(vaddr);
nvmap_altfree(td_array, online_cpus * sizeof(*td_array));
goto page_by_page_flush;
}
if (check_sub_overflow((size_t)numpages, sub_total_pages, &rem_pages)) {
vunmap(vaddr);
nvmap_altfree(td_array, online_cpus * sizeof(*td_array));
goto page_by_page_flush;
}
last_set_size = rem_pages << PAGE_SHIFT;
for (i = 0; i < online_cpus; i++) { for (i = 0; i < online_cpus; i++) {
td_array[i] = nvmap_altalloc(sizeof(struct nvmap_cache_thread)); td_array[i] = nvmap_altalloc(sizeof(struct nvmap_cache_thread));
@@ -107,12 +120,18 @@ void nvmap_clean_cache(struct page **pages, int numpages)
td_array[i]->thread_id = i + 1; td_array[i]->thread_id = i + 1;
td_array[i]->size = (i == online_cpus - 1) ? last_set_size : set_size; td_array[i]->size = (i == online_cpus - 1) ? last_set_size : set_size;
td_array[i]->va_start = vaddr + i * set_size; if (check_mul_overflow((size_t)i, set_size, &temp)) {
nvmap_altfree(td_array[i], sizeof(struct nvmap_cache_thread));
goto stop_threads;
}
td_array[i]->va_start = vaddr + temp;
td_array[i]->task = kthread_run( td_array[i]->task = kthread_run(
threaded_cache_flush, td_array[i], threaded_cache_flush, td_array[i],
"nvmap_cache_flush_thread_%d", i); "nvmap_cache_flush_thread_%d", i);
if (IS_ERR(td_array[i]->task)) { if (IS_ERR(td_array[i]->task)) {
pr_err("failed to create kernel thread:%d\n", i); pr_err("failed to create kernel thread:%d\n", i);
nvmap_altfree(td_array[i], sizeof(struct nvmap_cache_thread));
goto stop_threads; goto stop_threads;
} }