Skip to content

Commit

Permalink
crypto: talitos - Prevent panic in probe error path
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Aaron Sierra authored and herbertx committed Aug 10, 2015
1 parent ab86ca0 commit 35a3bb3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
13 changes: 11 additions & 2 deletions drivers/crypto/talitos.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,21 +766,30 @@ 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,
priv->rng.data_present = talitos_rng_data_present,
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;
}

/*
Expand Down Expand Up @@ -2673,7 +2682,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);
Expand Down
1 change: 1 addition & 0 deletions drivers/crypto/talitos.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 35a3bb3

Please sign in to comment.