Skip to content

Commit

Permalink
ata: libahci: Fix devres cleanup on failure
Browse files Browse the repository at this point in the history
Commit c7d7dde ("ata: libahci: Allow using multiple regulators")
releases regulators during ahci_platform_put_resources(). That doesn't
work because the function is run as part of the devres machinery. Such
resources are torn down in reverse order. Since the array that holds
pointers to the regulators is allocated using devres after the device
context to which ahci_platform_put_resources() is attached, the memory
will be freed before calling ahci_platform_put_resources() and thereby
causing a use-after-free error.

This commit fixes this by using regular allocations for the array. The
memory can then be freed after the regulators have been released. This
conserves the advantages of using the managed API.

Reported-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
  • Loading branch information
Thierry Reding authored and Tejun Heo committed Jan 21, 2015
1 parent c7d7dde commit 5529415
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion drivers/ata/libahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ static void ahci_platform_put_resources(struct device *dev, void *res)
if (hpriv->target_pwrs && hpriv->target_pwrs[c])
regulator_put(hpriv->target_pwrs[c]);

kfree(hpriv->target_pwrs);
}

static int ahci_platform_get_phy(struct ahci_host_priv *hpriv, u32 port,
Expand Down Expand Up @@ -412,7 +413,7 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
goto err_out;
}
sz = hpriv->nports * sizeof(*hpriv->target_pwrs);
hpriv->target_pwrs = devm_kzalloc(dev, sz, GFP_KERNEL);
hpriv->target_pwrs = kzalloc(sz, GFP_KERNEL);
if (!hpriv->target_pwrs) {
rc = -ENOMEM;
goto err_out;
Expand Down

0 comments on commit 5529415

Please sign in to comment.