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>
This commit is contained in:
parent
a68f6610d4
commit
ed94070058
|
@ -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)
|
||||||
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 @@ empty_rbuf:
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
|
|
||||||
|
|
Reference in New Issue