diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-13 07:11:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-13 07:11:14 -0700 |
commit | 0898d2aa9db8b7770c83590d0326d0e6b62cef2b (patch) | |
tree | 2383c0909c94b389ec75412748aced1678cf5967 /lib | |
parent | 5a7d8a28080caed7fd4cb1b81d092adac4445e8e (diff) | |
parent | 26052f9b9bb8de4f6a57165b0a803de9c26138bd (diff) | |
download | op-kernel-dev-0898d2aa9db8b7770c83590d0326d0e6b62cef2b.zip op-kernel-dev-0898d2aa9db8b7770c83590d0326d0e6b62cef2b.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
"This fixes a 7+ year race condition in the crypto API that causes
sporadic crashes when multiple threads load the same algorithm.
It also fixes the crct10dif algorithm again to prevent boot failures
on systems where the initramfs tool ignores module softdeps"
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: crct10dif - Add fallback for broken initrds
crypto: api - Fix race condition in larval lookup
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crc-t10dif.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c index 43bc5b0..dfe6ec1 100644 --- a/lib/crc-t10dif.c +++ b/lib/crc-t10dif.c @@ -14,8 +14,10 @@ #include <linux/err.h> #include <linux/init.h> #include <crypto/hash.h> +#include <linux/static_key.h> static struct crypto_shash *crct10dif_tfm; +static struct static_key crct10dif_fallback __read_mostly; __u16 crc_t10dif(const unsigned char *buffer, size_t len) { @@ -25,6 +27,9 @@ __u16 crc_t10dif(const unsigned char *buffer, size_t len) } desc; int err; + if (static_key_false(&crct10dif_fallback)) + return crc_t10dif_generic(0, buffer, len); + desc.shash.tfm = crct10dif_tfm; desc.shash.flags = 0; *(__u16 *)desc.ctx = 0; @@ -39,7 +44,11 @@ EXPORT_SYMBOL(crc_t10dif); static int __init crc_t10dif_mod_init(void) { crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0); - return PTR_RET(crct10dif_tfm); + if (IS_ERR(crct10dif_tfm)) { + static_key_slow_inc(&crct10dif_fallback); + crct10dif_tfm = NULL; + } + return 0; } static void __exit crc_t10dif_mod_fini(void) |