Re: [PATCH 5/7] hw/core/machine: free machine->fdt in machine_finalize()

Akihiko Odaki <[email protected]> Sun, 26 Jul 2026 17:54:50 +0900
Newsgroups org.kernel.vger.linux-cxl,org.nongnu.qemu-devel
Message-ID <[email protected]>
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);
>