diff options
author | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2009-07-03 00:09:41 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-07-03 00:09:41 -0400 |
commit | ed94070058033a3c99fe62c90d00c39dc443c679 (patch) | |
tree | 5ae19b435f0903e67834e10ddccec2be4cfa4ab6 | |
parent | a68f6610d4f1ebe61818f5926fa8fa9e75d06a95 (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.c | 9 |
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 */ |
188 | static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) | 188 | static 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 | ||
270 | done: | 269 | done: |
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; |
334 | out: | 333 | out: |
335 | spin_unlock(&ctx->prng_lock); | 334 | spin_unlock_bh(&ctx->prng_lock); |
336 | 335 | ||
337 | return rc; | 336 | return rc; |
338 | 337 | ||