On Thu, Aug 7, 2025 at 5:18 AM Zhen Ni zhen.ni@easystack.cn wrote:
acpi_put_table() is only called when kobject_create_and_add() or fpdt_process_subtable() fails, but not on the success path. This causes a memory leak if initialization succeeds.
No, it doesn't, or at least not in the usual sense.
Memory occupied by ACPI tables is mapped in place, so even if you call acpi_put_table(), the table is still there except that the memory occupied by it is not mapped.
Ensure acpi_put_table() is called in all cases by adding a put_table label and routing both success and failure paths through it. Drop the err_subtable label since kobject_put() is only needed when fpdt_process_subtable() fails.
So this can be done so long as the table is never used going forward, but it is not strictly necessary as per the above.
Fixes: d1eb86e59be0 ("ACPI: tables: introduce support for FPDT table") Cc: stable@vger.kernel.org
Not really.
Signed-off-by: Zhen Ni zhen.ni@easystack.cn
drivers/acpi/acpi_fpdt.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c index 271092f2700a..c8aea5bb187c 100644 --- a/drivers/acpi/acpi_fpdt.c +++ b/drivers/acpi/acpi_fpdt.c @@ -275,7 +275,7 @@ static int __init acpi_init_fpdt(void) struct acpi_table_header *header; struct fpdt_subtable_entry *subtable; u32 offset = sizeof(*header);
int result;
int result = 0; status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);
@@ -285,7 +285,7 @@ static int __init acpi_init_fpdt(void) fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj); if (!fpdt_kobj) { result = -ENOMEM;
goto err_nomem;
goto put_table; } while (offset < header->length) {
@@ -295,8 +295,10 @@ static int __init acpi_init_fpdt(void) case SUBTABLE_S3PT: result = fpdt_process_subtable(subtable->address, subtable->type);
if (result)
goto err_subtable;
if (result) {
kobject_put(fpdt_kobj);
goto put_table;
} break; default: /* Other types are reserved in ACPI 6.4 spec. */
@@ -304,11 +306,8 @@ static int __init acpi_init_fpdt(void) } offset += sizeof(*subtable); }
return 0;
-err_subtable:
kobject_put(fpdt_kobj);
-err_nomem: +put_table: acpi_put_table(header); return result; } --