[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] bootfdt: Fix infinite loop in device_tree_for_each_node()


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Dmytro Prokopchuk1 <dmytro_prokopchuk1@xxxxxxxx>
  • Date: Sat, 20 Jun 2026 11:49:42 +0000
  • Accept-language: en-US, uk-UA, ru-RU
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RgOJD8ntZfOlkW/kijKbSf5fRZRO2WfY2Wuakesj53M=; b=DFJ8oBbXbKfcwNw244P7IjNBZa63V7IzFjIGqTcGBP+FuxkrIagsTxdpw/jdBRGlkDVi4E/HZ/+xYYtjzDGq1JTGVzPCm4IsaHI/uWsQhBufsHzE1wrAvd2zwR8/d8mfbSLR4p75Oq/Jl+PsOAWb+zVB9JdAz9vluLKe7HYCWwqSUar+4vvSza1CsBe+M3ziKAThuHZaNaJPu7B+yPP/YO0/V8oqwtYh5F8h+axqP5T5u2oXL108sw6ZoEO7MxC7RI//Xt+kKluNVNvACix6yQCSuM2OG6GOnl04Qi+xXD7Xm+/2bGI2FHwg+oZLbfmdiSNy75lNiHOug74UxIb3rQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZUeiX9jAbBl133WEfkwpHIJOauchUn6BvBE44sPjzhkSChZ8eM6brqnwD3HHrMg8sazCciPuBcAgYgOn/AFbkoqDTtBq4ncMyyDr5CqMJ/7joSLdYzHkcYoNblP9WQPFrVI3f8jToyCZ5QkhnY0jYVzGEMRzW/ak+GDzRA6h3M4IOUG3XnBbMyc44QalVruoqnqc7DamMVAV/66ry0kG926Tke5jsB07k8Yj+Aca6a0kcFcd8JePPO8WzMEduNyCBo9OOY95UmzF4dllygpHhquKTjkUuu4HcnA2qIxyoVh9p/hgFR/lNBg4k0ahBh5/AIjsGBO4vavn01Acf6IZGA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=epam.com header.i="@epam.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Dmytro Prokopchuk1 <dmytro_prokopchuk1@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Sat, 20 Jun 2026 11:49:54 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHdAKriIPevU8UYiUCGOtgPRNoJOg==
  • Thread-topic: [PATCH] bootfdt: Fix infinite loop in device_tree_for_each_node()

When a node's depth exceeds DEVICE_TREE_MAX_DEPTH inside the
device_tree_for_each_node() loop, the code prints a warning and
executes 'continue;' statement, which jumps to condition check,
bypassing the iterator update step:

    node = fdt_next_node(fdt, node, &depth).

The node and depth are not updated, the loop repeatedly evaluates
the same too-deep node, causing a hang.

Fix this by wrapping the node processing logic in an 'else' block.
This ensures the loop update step is executed on every iteration,
safely skipping deeply nested nodes and doing the traversal.

Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@xxxxxxxx>
---

Test CI pipeline: 
https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/2615174670

Local tests.
Tests were based on "qemu-xtf.sh".
In the "/chosen" node were added these "levelN" nesting nodes:

        chosen {
                stdout-path = "/pl011@9000000";
                kaslr-seed = <0x6ae81a67 0x26e92d62>;
        level1 {
            level2 {
        ...
                        level19 {
                            level20 {
                                compatible = "test";
                                value = <1234>;
                            };
                        };
        ...
            };
        };
        };

Without a patch Xen stuck printing the same message in a loop:

(XEN) Checking for initrd in /chosen
(XEN) Checking for "xen,static-mem" in domain node
(XEN) Warning: device tree node `level15' is nested too deep
(XEN) Warning: device tree node `level15' is nested too deep
(XEN) Warning: device tree node `level15' is nested too deep
(XEN) Warning: device tree node `level15' is nested too deep
(XEN) Warning: device tree node `level15' is nested too deep
...

With a patch these too-deep nodes were successfully skipped and Xen
continued to boot:

(XEN) Checking for initrd in /chosen
(XEN) Checking for "xen,static-mem" in domain node
(XEN) Warning: device tree node `level15' is nested too deep
(XEN) Warning: device tree node `level16' is nested too deep
(XEN) Warning: device tree node `level17' is nested too deep
(XEN) Warning: device tree node `level18' is nested too deep
(XEN) Warning: device tree node `level19' is nested too deep
(XEN) Warning: device tree node `level20' is nested too deep
(XEN) RAM: 0000000040000000 - 00000000bfffffff
(XEN) 
(XEN) MODULE[0]: 0000000043200000 - 000000004337afff Xen         
(XEN) MODULE[1]: 0000000043400000 - 0000000043402fff Device Tree 
(XEN) MODULE[2]: 0000000043000000 - 00000000430ef7f6 Ramdisk     
(XEN) MODULE[3]: 0000000040600000 - 0000000042f4ffff Kernel      
(XEN) MODULE[4]: 0000000040400000 - 0000000040412fff Kernel      
(XEN) 
(XEN) CMDLINE[0000000040600000]:domU0 console=ttyAMA0
...

---
 xen/common/device-tree/bootfdt.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c
index 7c790b9a4d..4d10013b2d 100644
--- a/xen/common/device-tree/bootfdt.c
+++ b/xen/common/device-tree/bootfdt.c
@@ -90,23 +90,24 @@ int __init device_tree_for_each_node(const void *fdt, int 
node,
         {
             printk("Warning: device tree node `%s' is nested too deep\n",
                    name);
-            continue;
         }
-
-        as = depth > 0 ? address_cells[depth-1] : 
DT_ROOT_NODE_ADDR_CELLS_DEFAULT;
-        ss = depth > 0 ? size_cells[depth-1] : DT_ROOT_NODE_SIZE_CELLS_DEFAULT;
-
-        address_cells[depth] = device_tree_get_u32(fdt, node,
-                                                   "#address-cells", as);
-        size_cells[depth] = device_tree_get_u32(fdt, node,
-                                                "#size-cells", ss);
-
-        /* skip the first node */
-        if ( node != first_node )
+        else
         {
-            ret = func(fdt, node, name, depth, as, ss, data);
-            if ( ret != 0 )
-                return ret;
+            as = depth > 0 ? address_cells[depth-1] : 
DT_ROOT_NODE_ADDR_CELLS_DEFAULT;
+            ss = depth > 0 ? size_cells[depth-1] : 
DT_ROOT_NODE_SIZE_CELLS_DEFAULT;
+
+            address_cells[depth] = device_tree_get_u32(fdt, node,
+                                                       "#address-cells", as);
+            size_cells[depth] = device_tree_get_u32(fdt, node,
+                                                    "#size-cells", ss);
+
+            /* skip the first node */
+            if ( node != first_node )
+            {
+                ret = func(fdt, node, name, depth, as, ss, data);
+                if ( ret != 0 )
+                    return ret;
+            }
         }
 
         node = fdt_next_node(fdt, node, &depth);
-- 
2.43.0



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.