summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammed Mirza Mandayappurath Manzoor <quic_mmandaya@quicinc.com>2023-09-08 15:46:15 -0700
committerGuus Sliepen <gsliepen@google.com>2023-10-17 06:00:05 +0000
commit77de1a60f1fbb6d5a58376403e24c6ecebd12c17 (patch)
tree79e3e799f28b4803103790e348f448059e1cdd08
parent6e095353adc3d05a90dbc7cc78ea9b8e68c70312 (diff)
downloadmsm-77de1a60f1fbb6d5a58376403e24c6ecebd12c17.tar.gz
msm: kgsl: Prevent wrap around during user address mapping
When setting svm region during the gpuobj import ioctl call for a usermem address, there is a possibility of a very large input size causing the region's 64-bit end address to wrap around. This can cause the region to incorrectly be considered valid, ultimately allowing a use after free scenario. To prevent this, detect the occurrence of a wrap and reject the import. Change-Id: I48b9cf37310943b4e5c3ff0a18deece13b016c03 Signed-off-by: Mohammed Mirza Mandayappurath Manzoor <quic_mmandaya@quicinc.com> Signed-off-by: Puranam V G Tejaswi <quic_pvgtejas@quicinc.com> Provenance: https://git.codelinaro.org/clo/la/kernel/msm-4.19/-/commit/d66b799c804083ea5226cfffac6d6c4e7ad4968b Bug: 299649795
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index e4b9924baec2..7ade01a215e5 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/compat.h>
@@ -2428,14 +2428,18 @@ static uint64_t kgsl_iommu_find_svm_region(struct kgsl_pagetable *pagetable,
static bool iommu_addr_in_svm_ranges(struct kgsl_iommu_pt *pt,
u64 gpuaddr, u64 size)
{
+ u64 end = gpuaddr + size;
+
+ /* Make sure size is not zero and we don't wrap around */
+ if (end <= gpuaddr)
+ return false;
+
if ((gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end) &&
- ((gpuaddr + size) > pt->compat_va_start &&
- (gpuaddr + size) <= pt->compat_va_end))
+ (end > pt->compat_va_start && end <= pt->compat_va_end))
return true;
if ((gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end) &&
- ((gpuaddr + size) > pt->svm_start &&
- (gpuaddr + size) <= pt->svm_end))
+ (end > pt->svm_start && end <= pt->svm_end))
return true;
return false;