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.

Issue: FP3SEC-1210
Change-Id: I4a88f56c58b830d4342e47dc1d1f6290c78ab6b4
Signed-off-by: Mohammed Mirza Mandayappurath Manzoor <quic_mmandaya@quicinc.com>
Signed-off-by: Sanjay Yadav <quic_sanjyada@quicinc.com>
(cherry picked from commit 89a22de4beb805fb3a4d0ed796078a5d45c02784)
(cherry picked from commit 8c567d2d4e6646da0fd3da8277dd311e245c9351)
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 3233589..a19d661 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,5 +1,5 @@
 /* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
- *
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. 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 version 2 and
  * only version 2 as published by the Free Software Foundation.
@@ -2431,14 +2431,18 @@
 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;