diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-12-09 18:45:28 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2007-02-06 17:20:58 -0500 |
commit | fb469840b8c34b2f95b40a64b271f245cc1075b7 (patch) | |
tree | 8013f8beb39c83b80be0e40195005b0482cea69b /crypto/xcbc.c | |
parent | 62d0cfcb27cf755cebdc93ca95dabc83608007cd (diff) |
[CRYPTO] all: Check for usage in hard IRQ context
Using blkcipher/hash crypto operations in hard IRQ context can lead
to random memory corruption due to the reuse of kmap_atomic slots.
Since crypto operations were never meant to be used in hard IRQ
contexts, this patch checks for such usage and returns an error
before kmap_atomic is performed.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/xcbc.c')
-rw-r--r-- | crypto/xcbc.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 9347eb6bcf69..317e9f08fc04 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/crypto.h> | 22 | #include <linux/crypto.h> |
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/hardirq.h> | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
26 | #include <linux/rtnetlink.h> | 27 | #include <linux/rtnetlink.h> |
@@ -108,9 +109,9 @@ static int crypto_xcbc_digest_init(struct hash_desc *pdesc) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
111 | static int crypto_xcbc_digest_update(struct hash_desc *pdesc, | 112 | static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, |
112 | struct scatterlist *sg, | 113 | struct scatterlist *sg, |
113 | unsigned int nbytes) | 114 | unsigned int nbytes) |
114 | { | 115 | { |
115 | struct crypto_hash *parent = pdesc->tfm; | 116 | struct crypto_hash *parent = pdesc->tfm; |
116 | struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); | 117 | struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); |
@@ -183,6 +184,15 @@ static int crypto_xcbc_digest_update(struct hash_desc *pdesc, | |||
183 | return 0; | 184 | return 0; |
184 | } | 185 | } |
185 | 186 | ||
187 | static int crypto_xcbc_digest_update(struct hash_desc *pdesc, | ||
188 | struct scatterlist *sg, | ||
189 | unsigned int nbytes) | ||
190 | { | ||
191 | if (WARN_ON_ONCE(in_irq())) | ||
192 | return -EDEADLK; | ||
193 | return crypto_xcbc_digest_update2(pdesc, sg, nbytes); | ||
194 | } | ||
195 | |||
186 | static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) | 196 | static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) |
187 | { | 197 | { |
188 | struct crypto_hash *parent = pdesc->tfm; | 198 | struct crypto_hash *parent = pdesc->tfm; |
@@ -234,8 +244,11 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) | |||
234 | static int crypto_xcbc_digest(struct hash_desc *pdesc, | 244 | static int crypto_xcbc_digest(struct hash_desc *pdesc, |
235 | struct scatterlist *sg, unsigned int nbytes, u8 *out) | 245 | struct scatterlist *sg, unsigned int nbytes, u8 *out) |
236 | { | 246 | { |
247 | if (WARN_ON_ONCE(in_irq())) | ||
248 | return -EDEADLK; | ||
249 | |||
237 | crypto_xcbc_digest_init(pdesc); | 250 | crypto_xcbc_digest_init(pdesc); |
238 | crypto_xcbc_digest_update(pdesc, sg, nbytes); | 251 | crypto_xcbc_digest_update2(pdesc, sg, nbytes); |
239 | return crypto_xcbc_digest_final(pdesc, out); | 252 | return crypto_xcbc_digest_final(pdesc, out); |
240 | } | 253 | } |
241 | 254 | ||