On 2026/07/25 23:00, Marc-André Lureau wrote:
machine->fdt is a plain g_malloc0() buffer (see create_device_tree())
that boards populate during MachineClass::init, but machine_finalize()
never freed it, unlike the other boot-time buffers (dtb, dumpdtb,
kernel_filename, ...). Free it for consistency.

This unfortunately converts an existing bug into double-free.

spapr_machine_reset() aliases machine->fdt to spapr->fdt_blob. spapr_dtb_pre_load() and h_update_dt() later free it via
spapr->fdt_blob, but does not update machine->fdt, making it dangling.

Leaving machine->fdt dangling is already a bug. do_client_architecture_support() explains that as follows:

    /*
     * Set the machine->fdt pointer again since we just freed
     * it above (by freeing spapr->fdt_blob). We set this
     * pointer to enable support for the 'dumpdtb' QMP/HMP
     * command.
     */
    MACHINE(spapr)->fdt = fdt;

This patch introduces another path to trigger the bug.

Regards,
Akihiko Odaki


Signed-off-by: Marc-André Lureau <[email protected]>
---
  hw/core/machine.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 805148678d57..2b24d711d76f 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1301,6 +1301,7 @@ static void machine_finalize(Object *obj)
      g_free(ms->kernel_cmdline);
      g_free(ms->dtb);
      g_free(ms->dumpdtb);
+    g_free(ms->fdt);
      g_free(ms->dt_compatible);
      g_free(ms->firmware);
      g_free(ms->device_memory);



Reply via email to