From: Markus Armbruster <arm...@redhat.com> At this moment, arm_load_dtb() can free machine->fdt when binfo->dtb_filename is NULL. If there's no 'dtb_filename', 'fdt' will be retrieved by binfo->get_dtb(). If get_dtb() returns machine->fdt, as is the case of machvirt_dtb() from hw/arm/virt.c, fdt now has a pointer to machine->fdt. And, in that case, the existing g_free(fdt) at the end of arm_load_dtb() will make machine->fdt point to an invalid memory region.
Since monitor command 'dumpdtb' was introduced a couple of releases ago, running it with any ARM machine that uses arm_load_dtb() will crash QEMU. Let's enable all arm_load_dtb() callers to use dumpdtb properly. Instead of freeing 'fdt', assign it back to ms->fdt. Cc: Peter Maydell <peter.mayd...@linaro.org> Cc: qemu-...@nongnu.org Fixes: bf353ad55590f ("qmp/hmp, device_tree.c: introduce dumpdtb") Reported-by: Markus Armbruster <arm...@redhat.com> Signed-off-by: Daniel Henrique Barboza <danielhb...@gmail.com> Signed-off-by: Markus Armbruster <arm...@redhat.com> Reviewed-by: Daniel Henrique Barboza <danielhb...@gmail.com> Message-id: 20230328165935.1512846-1-arm...@redhat.com Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> (cherry picked from commit 12148d442ec3f4386c8624ffcf44c61a8b344018) Signed-off-by: Michael Tokarev <m...@tls.msk.ru> --- hw/arm/boot.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 15c2bf1867..725bab8adc 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -686,7 +686,10 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, rom_ptr_for_as(as, addr, size)); - g_free(fdt); + if (fdt != ms->fdt) { + g_free(ms->fdt); + ms->fdt = fdt; + } return size; -- 2.30.2