[PATCH v2025.09.y 11/49] range: fix corner cases when exclusive end is zero
Ahmad Fatoum
a.fatoum at pengutronix.de
Fri Dec 19 01:20:47 PST 2025
From: Ahmad Fatoum <a.fatoum at barebox.org>
Unlike inclusive ranges, exclusive ranges can be empty and
region_overlap_end_exclusive() goes beyond that and checks that ranges
are neither empty nor does the end precede the start.
This is problematic for a range that stretches to the maximum value of a
type. Exclusive end in that case would be 0 and 0 comes before all
non-zero numbers, so the region_overlap_end_exclusive() would always
return false.
Fix this by normalizing end to be inclusive first thing in the function.
And for extra safety, enforce that the function may only be called with
arguments that are all of the same unsigned type.
This resolves a MMU hang on an STM32MP1 board with 1G RAM that had
memory stretching from 0xc00000000 to 0xffffffff inclusive as
remap_range_end_sans_text() would not detect the text area overlap and
then all of RAM, including where barebox is running from would be mapped
non-executable.
Fixes: 768fdb36f30e ("partition: define new region_overlap_end_exclusive helper")
Reported-by: Sohaib Mohamed <sohaib.amhmd at gmail.com>
Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
Link: https://lore.barebox.org/20251101105542.3830943-1-a.fatoum@barebox.org
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
(cherry picked from commit 3e2d06afabe166e575c66e3d9faa2070933ebb1c)
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
include/range.h | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/include/range.h b/include/range.h
index bb41dc78ac43..b5dc5cdb4d39 100644
--- a/include/range.h
+++ b/include/range.h
@@ -3,6 +3,8 @@
#define _RANGE_H__
#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/build_bug.h>
/**
* region_overlap_end_inclusive - check whether a pair of [start, end] ranges overlap
@@ -29,17 +31,26 @@ static inline bool region_overlap_end_inclusive(u64 starta, u64 enda,
* @enda: end of the first range (exclusive)
* @startb: start of the second range
* @endb: end of the second range (exclusive)
+ *
+ * NOTE: end of zero is always interpreted to mean including the maximum
+ * value of the type.
*/
-static inline bool region_overlap_end_exclusive(u64 starta, u64 enda,
- u64 startb, u64 endb)
-{
- /* Empty ranges don't overlap */
- if (starta >= enda || startb >= endb)
- return false;
-
- return region_overlap_end_inclusive(starta, enda - 1,
- startb, endb - 1);
-}
+#define region_overlap_end_exclusive(starta, enda, startb, endb) \
+({ \
+ u64 __starta = (starta), __enda = (enda) - 1; \
+ u64 __startb = (startb), __endb = (endb) - 1; \
+ \
+ static_assert(__same_type((starta), (enda))); \
+ static_assert(__same_type((enda), (startb))); \
+ static_assert(__same_type((startb), (endb))); \
+ static_assert(((typeof(endb))-1) > 0); \
+ \
+ /* Empty ranges don't overlap */ \
+ (__starta <= __enda && __startb <= __endb) \
+ ? region_overlap_end_inclusive(__starta, __enda, \
+ __startb, __endb) \
+ : false; \
+})
/**
--
2.47.3
More information about the barebox
mailing list