hw/i386/acpi-build.c: Fix memory leak in acpi_build_tables_cleanup()

There are three ACPI tables: 'linker_data', 'rsdp' and 'table_data'. They are
used differently. Two of them are being copied before using and only the copy
is used later. But the third is used directly. Because of that we need to free
two tables completely and delete only wrapper for the third one.

Valgrind output:
==23931== 131,072 bytes in 1 blocks are definitely lost in loss record 7,729 of 7,734
==23931==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23931==    by 0x2EA920: realloc_and_trace (vl.c:2811)
==23931==    by 0x509E6AE: g_realloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==23931==    by 0x506DB32: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==23931==    by 0x506E463: g_array_set_size (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
==23931==    by 0x256A4F: acpi_align_size (acpi-build.c:487)
==23931==    by 0x259F92: acpi_build (acpi-build.c:1601)
==23931==    by 0x25A212: acpi_setup (acpi-build.c:1682)
==23931==    by 0x24F346: pc_guest_info_machine_done (pc.c:1110)
==23931==    by 0x55FAAB: notifier_list_notify (notify.c:39)
==23931==    by 0x2EA704: qemu_run_machine_init_done_notifiers (vl.c:2759)
==23931==    by 0x2EEC3C: main (vl.c:4504)

Signed-off-by: Nikita Belov <zodiac@ispras.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
Nikita Belov 2014-10-29 18:07:02 +04:00 committed by Michael S. Tsirkin
parent caad057bb6
commit ac369a7796

View File

@ -1502,11 +1502,9 @@ static inline void acpi_build_tables_init(AcpiBuildTables *tables)
static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
{ {
void *linker_data = bios_linker_loader_cleanup(tables->linker); void *linker_data = bios_linker_loader_cleanup(tables->linker);
if (mfre) { g_free(linker_data);
g_free(linker_data);
}
g_array_free(tables->rsdp, mfre); g_array_free(tables->rsdp, mfre);
g_array_free(tables->table_data, mfre); g_array_free(tables->table_data, true);
g_array_free(tables->tcpalog, mfre); g_array_free(tables->tcpalog, mfre);
} }