aboutsummaryrefslogtreecommitdiff
path: root/lib/fdtdec.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2022-12-21 16:08:21 -0700
committerSimon Glass <sjg@chromium.org>2023-01-18 11:49:13 -0700
commit9557592edc82cc690db2e81ef249a772f60078cb (patch)
treedb3e536d874bf16a81b118f7980cbbe31920708e /lib/fdtdec.c
parentec4f327145ead89a5fd6714baa878112818b7147 (diff)
downloadu-boot-9557592edc82cc690db2e81ef249a772f60078cb.zip
u-boot-9557592edc82cc690db2e81ef249a772f60078cb.tar.gz
u-boot-9557592edc82cc690db2e81ef249a772f60078cb.tar.bz2
fdt: Check for overlapping data and FDT
If the FDT overlaps with the data region of the image, or with the stack, it can become corrupted before relocation. Add a check for this, behind a debug flag, as it can be very confusing and time-consuming to debug. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib/fdtdec.c')
-rw-r--r--lib/fdtdec.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 03c9cea..8d5c688 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1231,6 +1231,29 @@ static void *fdt_find_separate(void)
#else
/* FDT is at end of image */
fdt_blob = (ulong *)&_end;
+
+ if (_DEBUG && !fdtdec_prepare_fdt(fdt_blob)) {
+ int stack_ptr;
+ const void *top = fdt_blob + fdt_totalsize(fdt_blob);
+
+ /*
+ * Perform a sanity check on the memory layout. If this fails,
+ * it indicates that the device tree is positioned above the
+ * global data pointer or the stack pointer. This should not
+ * happen.
+ *
+ * If this fails, check that SYS_INIT_SP_ADDR has enough space
+ * below it for SYS_MALLOC_F_LEN and global_data, as well as the
+ * stack, without overwriting the device tree or U-Boot itself.
+ * Since the device tree is sitting at _end (the start of the
+ * BSS region), we need the top of the device tree to be below
+ * any memory allocated by board_init_f_alloc_reserve().
+ */
+ if (top > (void *)gd || top > (void *)&stack_ptr) {
+ printf("FDT %p gd %p\n", fdt_blob, gd);
+ panic("FDT overlap");
+ }
+ }
#endif
return fdt_blob;