diff mbox

[v2] crypto: talitos: Prevent panic in probe error path

Message ID 355366700.773095.1438811528320.JavaMail.zimbra@xes-inc.com (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show

Commit Message

Aaron Sierra Aug. 5, 2015, 9:52 p.m. UTC
The probe error path for this driver, for all intents and purposes,
is the talitos_remove() function due to the common "goto err_out".

Without this patch applied, talitos_remove() will panic under these
two conditions:

1. If the RNG device hasn't been registered via
   talitos_register_rng() prior to entry into talitos_remove(),
   then the attempt to unregister the RNG "device" will cause a panic.

2. If the priv->chan array has not been allocated prior to entry
   into talitos_remove(), then the per-channel FIFO cleanup will panic
   because of the dereference of that NULL "array".

Both of the above scenarios occur if talitos_probe_irq() fails.

This patch resolves issue #1 by introducing a boolean to mask the
hwrng_unregister() call in talitos_unregister_rng() if RNG device
registration was unsuccessful.

It resolves issue #2 by checking that priv->chan is not NULL in the
per-channel FIFO cleanup for loop.

For completeness, this patch also sets device drvdata to NULL after
the private structure is freed in talitos_remove().

Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
---
 drivers/crypto/talitos.c | 14 ++++++++++++--
 drivers/crypto/talitos.h |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

Comments

Aaron Sierra Aug. 6, 2015, 6:45 p.m. UTC | #1
> For completeness, this patch also sets device drvdata to NULL after
> the private structure is freed in talitos_remove().

[snip]

> @@ -2745,6 +2754,7 @@ static int talitos_remove(struct platform_device
> *ofdev)
>  	iounmap(priv->reg);
>  
>  	kfree(priv);
> +	dev_set_drvdata(dev, NULL);
>  
>  	return 0;
>  }

I just found this drvdata cleanup hasn't been required for a few years,
due to the following commit:

    commit 0998d0631001288a5974afc0b2a5f568bcdecb4d
    Author: Hans de Goede <hdegoede@redhat.com>
    Date:   Wed May 23 00:09:34 2012 +0200

        device-core: Ensure drvdata = NULL when no driver is bound

Should I submit a v3 patch without this cleanup, assuming there aren't
other changes requested?

-Aaron
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Herbert Xu Aug. 10, 2015, 3:41 p.m. UTC | #2
On Thu, Aug 06, 2015 at 01:45:42PM -0500, Aaron Sierra wrote:
>
> I just found this drvdata cleanup hasn't been required for a few years,
> due to the following commit:
> 
>     commit 0998d0631001288a5974afc0b2a5f568bcdecb4d
>     Author: Hans de Goede <hdegoede@redhat.com>
>     Date:   Wed May 23 00:09:34 2012 +0200
> 
>         device-core: Ensure drvdata = NULL when no driver is bound
> 
> Should I submit a v3 patch without this cleanup, assuming there aren't
> other changes requested?

I have applied your patch with the dev_set_drvdata change removed.

Thanks,
diff mbox

Patch

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 83aca95..74f1a62 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -766,6 +766,7 @@  static int talitos_rng_init(struct hwrng *rng)
 static int talitos_register_rng(struct device *dev)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
+	int err;
 
 	priv->rng.name		= dev_driver_string(dev),
 	priv->rng.init		= talitos_rng_init,
@@ -773,14 +774,22 @@  static int talitos_register_rng(struct device *dev)
 	priv->rng.data_read	= talitos_rng_data_read,
 	priv->rng.priv		= (unsigned long)dev;
 
-	return hwrng_register(&priv->rng);
+	err = hwrng_register(&priv->rng);
+	if (!err)
+		priv->rng_registered = true;
+
+	return err;
 }
 
 static void talitos_unregister_rng(struct device *dev)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
 
+	if (!priv->rng_registered)
+		return;
+
 	hwrng_unregister(&priv->rng);
+	priv->rng_registered = false;
 }
 
 /*
@@ -2727,7 +2736,7 @@  static int talitos_remove(struct platform_device *ofdev)
 	if (hw_supports(dev, DESC_HDR_SEL0_RNG))
 		talitos_unregister_rng(dev);
 
-	for (i = 0; i < priv->num_channels; i++)
+	for (i = 0; priv->chan && i < priv->num_channels; i++)
 		kfree(priv->chan[i].fifo);
 
 	kfree(priv->chan);
@@ -2745,6 +2754,7 @@  static int talitos_remove(struct platform_device *ofdev)
 	iounmap(priv->reg);
 
 	kfree(priv);
+	dev_set_drvdata(dev, NULL);
 
 	return 0;
 }
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 163cfe7..0090f32 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -149,6 +149,7 @@  struct talitos_private {
 
 	/* hwrng device */
 	struct hwrng rng;
+	bool rng_registered;
 };
 
 extern int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,