common/memsize.c: Fix get_effective_memsize() to check for overflow
authorPali Rohár <pali@kernel.org>
Fri, 9 Sep 2022 15:32:39 +0000 (17:32 +0200)
committerTom Rini <trini@konsulko.com>
Fri, 23 Sep 2022 19:11:13 +0000 (15:11 -0400)
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

index 31884ac..3c80ad2 100644 (file)
@@ -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
 }