Commit ed940700 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Herbert Xu

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: default avatarSebastian Andrzej Siewior <sebastian@breakpoint.cc>
Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent a68f6610
...@@ -187,7 +187,6 @@ static int _get_more_prng_bytes(struct prng_context *ctx) ...@@ -187,7 +187,6 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
/* Our exported functions */ /* Our exported functions */
static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
{ {
unsigned long flags;
unsigned char *ptr = buf; unsigned char *ptr = buf;
unsigned int byte_count = (unsigned int)nbytes; unsigned int byte_count = (unsigned int)nbytes;
int err; int err;
...@@ -196,7 +195,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) ...@@ -196,7 +195,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
if (nbytes < 0) if (nbytes < 0)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&ctx->prng_lock, flags); spin_lock_bh(&ctx->prng_lock);
err = -EINVAL; err = -EINVAL;
if (ctx->flags & PRNG_NEED_RESET) if (ctx->flags & PRNG_NEED_RESET)
...@@ -268,7 +267,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) ...@@ -268,7 +267,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
goto remainder; goto remainder;
done: 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", dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
err, ctx); err, ctx);
return err; return err;
...@@ -287,7 +286,7 @@ static int reset_prng_context(struct prng_context *ctx, ...@@ -287,7 +286,7 @@ static int reset_prng_context(struct prng_context *ctx,
int rc = -EINVAL; int rc = -EINVAL;
unsigned char *prng_key; unsigned char *prng_key;
spin_lock(&ctx->prng_lock); spin_lock_bh(&ctx->prng_lock);
ctx->flags |= PRNG_NEED_RESET; ctx->flags |= PRNG_NEED_RESET;
prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY; prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
...@@ -332,7 +331,7 @@ static int reset_prng_context(struct prng_context *ctx, ...@@ -332,7 +331,7 @@ static int reset_prng_context(struct prng_context *ctx,
rc = 0; rc = 0;
ctx->flags &= ~PRNG_NEED_RESET; ctx->flags &= ~PRNG_NEED_RESET;
out: out:
spin_unlock(&ctx->prng_lock); spin_unlock_bh(&ctx->prng_lock);
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment