tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak
authorHanjun Guo <guohanjun@huawei.com>
Thu, 17 Nov 2022 11:23:41 +0000 (19:23 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jan 2023 08:26:36 +0000 (09:26 +0100)
commit 37e90c374dd11cf4919c51e847c6d6ced0abc555 upstream.

In crb_acpi_add(), we get the TPM2 table to retrieve information
like start method, and then assign them to the priv data, so the
TPM2 table is not used after the init, should be freed, call
acpi_put_table() to fix the memory leak.

Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
Cc: stable@vger.kernel.org
Signed-off-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/tpm/tpm_crb.c

index ccc3eb40672a4cdec847381a1ac5d4bfc5c6930b..dc78918562fd42a4a2d2c1d0edb93361e2ea3a25 100644 (file)
@@ -613,12 +613,16 @@ static int crb_acpi_add(struct acpi_device *device)
 
        /* Should the FIFO driver handle this? */
        sm = buf->start_method;
-       if (sm == ACPI_TPM2_MEMORY_MAPPED)
-               return -ENODEV;
+       if (sm == ACPI_TPM2_MEMORY_MAPPED) {
+               rc = -ENODEV;
+               goto out;
+       }
 
        priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
+       if (!priv) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
        /* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs
         * report only ACPI start but in practice seems to require both
@@ -638,7 +642,8 @@ static int crb_acpi_add(struct acpi_device *device)
                                FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
                                buf->header.length,
                                ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto out;
                }
                crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
                priv->smc_func_id = crb_smc->smc_func_id;
@@ -647,17 +652,23 @@ static int crb_acpi_add(struct acpi_device *device)
 
        rc = crb_map_io(device, priv, buf);
        if (rc)
-               return rc;
+               goto out;
 
        chip = tpmm_chip_alloc(dev, &tpm_crb);
-       if (IS_ERR(chip))
-               return PTR_ERR(chip);
+       if (IS_ERR(chip)) {
+               rc = PTR_ERR(chip);
+               goto out;
+       }
 
        dev_set_drvdata(&chip->dev, priv);
        chip->acpi_dev_handle = device->handle;
        chip->flags = TPM_CHIP_FLAG_TPM2;
 
-       return tpm_chip_register(chip);
+       rc = tpm_chip_register(chip);
+
+out:
+       acpi_put_table((struct acpi_table_header *)buf);
+       return rc;
 }
 
 static int crb_acpi_remove(struct acpi_device *device)