summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <sebastian@breakpoint.cc>2009-07-03 06:09:41 +0200
committerHerbert Xu <herbert@gondor.apana.org.au>2009-07-03 06:09:41 +0200
commited94070058033a3c99fe62c90d00c39dc443c679 (patch)
tree5ae19b435f0903e67834e10ddccec2be4cfa4ab6
parentcrypto: testmgr - Allow implementation-specific tests (diff)
downloadlinux-ed94070058033a3c99fe62c90d00c39dc443c679.tar.xz
linux-ed94070058033a3c99fe62c90d00c39dc443c679.zip
crypto: ansi_prng - Use just a BH lock
The current code uses a mix of sping_lock() & spin_lock_irqsave(). This can lead to deadlock with the correct timming & cprng_get_random() + cprng_reset() sequence. I've converted them to bottom half locks since all three user grab just a BH lock so this runs probably in softirq :) Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/ansi_cprng.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index d80ed4c1e009..ff00b58c2cdc 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -187,7 +187,6 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
/* Our exported functions */
static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
{
- unsigned long flags;
unsigned char *ptr = buf;
unsigned int byte_count = (unsigned int)nbytes;
int err;
@@ -196,7 +195,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
if (nbytes < 0)
return -EINVAL;
- spin_lock_irqsave(&ctx->prng_lock, flags);
+ spin_lock_bh(&ctx->prng_lock);
err = -EINVAL;
if (ctx->flags & PRNG_NEED_RESET)
@@ -268,7 +267,7 @@ empty_rbuf:
goto remainder;
done:
- spin_unlock_irqrestore(&ctx->prng_lock, flags);
+ spin_unlock_bh(&ctx->prng_lock);
dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
err, ctx);
return err;
@@ -287,7 +286,7 @@ static int reset_prng_context(struct prng_context *ctx,
int rc = -EINVAL;
unsigned char *prng_key;
- spin_lock(&ctx->prng_lock);
+ spin_lock_bh(&ctx->prng_lock);
ctx->flags |= PRNG_NEED_RESET;
prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
@@ -332,7 +331,7 @@ static int reset_prng_context(struct prng_context *ctx,
rc = 0;
ctx->flags &= ~PRNG_NEED_RESET;
out:
- spin_unlock(&ctx->prng_lock);
+ spin_unlock_bh(&ctx->prng_lock);
return rc;