aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <sebastian@breakpoint.cc>2009-07-03 00:09:41 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2009-07-03 00:09:41 -0400
commited94070058033a3c99fe62c90d00c39dc443c679 (patch)
tree5ae19b435f0903e67834e10ddccec2be4cfa4ab6
parenta68f6610d4f1ebe61818f5926fa8fa9e75d06a95 (diff)
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)
187/* Our exported functions */ 187/* Our exported functions */
188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) 188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
189{ 189{
190 unsigned long flags;
191 unsigned char *ptr = buf; 190 unsigned char *ptr = buf;
192 unsigned int byte_count = (unsigned int)nbytes; 191 unsigned int byte_count = (unsigned int)nbytes;
193 int err; 192 int err;
@@ -196,7 +195,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
196 if (nbytes < 0) 195 if (nbytes < 0)
197 return -EINVAL; 196 return -EINVAL;
198 197
199 spin_lock_irqsave(&ctx->prng_lock, flags); 198 spin_lock_bh(&ctx->prng_lock);
200 199
201 err = -EINVAL; 200 err = -EINVAL;
202 if (ctx->flags & PRNG_NEED_RESET) 201 if (ctx->flags & PRNG_NEED_RESET)
@@ -268,7 +267,7 @@ empty_rbuf:
268 goto remainder; 267 goto remainder;
269 268
270done: 269done:
271 spin_unlock_irqrestore(&ctx->prng_lock, flags); 270 spin_unlock_bh(&ctx->prng_lock);
272 dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n", 271 dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
273 err, ctx); 272 err, ctx);
274 return err; 273 return err;
@@ -287,7 +286,7 @@ static int reset_prng_context(struct prng_context *ctx,
287 int rc = -EINVAL; 286 int rc = -EINVAL;
288 unsigned char *prng_key; 287 unsigned char *prng_key;
289 288
290 spin_lock(&ctx->prng_lock); 289 spin_lock_bh(&ctx->prng_lock);
291 ctx->flags |= PRNG_NEED_RESET; 290 ctx->flags |= PRNG_NEED_RESET;
292 291
293 prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY; 292 prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
@@ -332,7 +331,7 @@ static int reset_prng_context(struct prng_context *ctx,
332 rc = 0; 331 rc = 0;
333 ctx->flags &= ~PRNG_NEED_RESET; 332 ctx->flags &= ~PRNG_NEED_RESET;
334out: 333out:
335 spin_unlock(&ctx->prng_lock); 334 spin_unlock_bh(&ctx->prng_lock);
336 335
337 return rc; 336 return rc;
338 337