From 777aaaa706bcfe08c284aed06886db7d482af3f8 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
Date: Fri, 9 Sep 2022 17:32:39 +0200
Subject: [PATCH] common/memsize.c: Fix get_effective_memsize() to check for
 overflow
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

Ensure that top of RAM can be represented by phys_size_t type. If RAM is
too large or RAM base address is too upper then limit RAM size to prevent
address space overflow.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
 common/memsize.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/common/memsize.c b/common/memsize.c
index 31884acca0..3c80ad2c83 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -94,11 +94,23 @@ long get_ram_size(long *base, long maxsize)
 
 phys_size_t __weak get_effective_memsize(void)
 {
+	phys_size_t ram_size = gd->ram_size;
+
+	/*
+	 * Check for overflow and limit ram size to some representable value.
+	 * It is required that ram_base + ram_size must be representable by
+	 * phys_size_t type and must be aligned by direct access, therefore
+	 * calculate it from last 4kB sector which should work as alignment
+	 * on any platform.
+	 */
+	if (gd->ram_base + ram_size < gd->ram_base)
+		ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base;
+
 #ifndef CONFIG_MAX_MEM_MAPPED
-	return gd->ram_size;
+	return ram_size;
 #else
 	/* limit stack to what we can reasonable map */
-	return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
-		CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+	return ((ram_size > CONFIG_MAX_MEM_MAPPED) ?
+		CONFIG_MAX_MEM_MAPPED : ram_size);
 #endif
 }
-- 
2.39.5