CVE-2014-9644: Improper Privilege Management (CWE-269)
value: The Crypto API in the Linux kernel before 3.18.5 allows local users to load arbitrary kernel modules via a bind system call for an AF_ALG socket with a parenthesized module template expression in the salg_name field, as demonstrated by the vfat(aes) expression, a different vulnerability than CVE-2013-7421.
CWE description: The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
Published: 2015-03-02T11:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: arch/x86/crypto/fpu.c, crypto/algapi.c, crypto/authenc.c, crypto/authencesn.c, crypto/cbc.c, crypto/ccm.c, crypto/chainiv.c, crypto/cmac.c, crypto/cryptd.c, crypto/ctr.c, crypto/cts.c, crypto/ecb.c, crypto/eseqiv.c, crypto/gcm.c, crypto/hmac.c, crypto/lrw.c, crypto/mcryptd.c, crypto/pcbc.c, crypto/pcrypt.c, crypto/seqiv.c, crypto/vmac.c, crypto/xcbc.c, crypto/xts.c
Commit date: 2014-11-26 20:06:30 +0800
Commit message: crypto: include crypto- module prefix in template

This adds the module loading prefix "crypto-" to the template lookup
as well.

For example, attempting to load 'vfat(blowfish)' via AF_ALG now correctly
includes the "crypto-" prefix at every level, correctly rejecting "vfat":

	net-pf-38
	algif-hash
	crypto-vfat(blowfish)
	crypto-vfat(blowfish)-all
	crypto-vfat

Reported-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Diff: diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c
index 98d7a188f46b07..f368ba261739fa 100644
--- a/arch/x86/crypto/fpu.c
+++ b/arch/x86/crypto/fpu.c
@@ -15,10 +15,11 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/crypto.h>
 #include <asm/i387.h>
 
 struct crypto_fpu_ctx {
 	struct crypto_blkcipher *child;
 };
@@ -157,5 +158,7 @@ int __init crypto_fpu_init(void)
 
 void __exit crypto_fpu_exit(void)
 {
 	crypto_unregister_template(&crypto_fpu_tmpl);
 }
+
+MODULE_ALIAS_CRYPTO("fpu");
diff --git a/crypto/algapi.c b/crypto/algapi.c
index e8d3a7dca8c488..71a8143e23b133 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -507,12 +507,12 @@ static struct crypto_template *__crypto_lookup_template(const char *name)
 	return tmpl;
 }
 
 struct crypto_template *crypto_lookup_template(const char *name)
 {
-	return try_then_request_module(__crypto_lookup_template(name), "%s",
-				       name);
+	return try_then_request_module(__crypto_lookup_template(name),
+				       "crypto-%s", name);
 }
 EXPORT_SYMBOL_GPL(crypto_lookup_template);
 
 int crypto_register_instance(struct crypto_template *tmpl,
 			     struct crypto_instance *inst)
diff --git a/crypto/authenc.c b/crypto/authenc.c
index e1223559d5dfd2..78fb16cab13f96 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -719,5 +719,6 @@ static void __exit crypto_authenc_module_exit(void)
 module_init(crypto_authenc_module_init);
 module_exit(crypto_authenc_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec");
+MODULE_ALIAS_CRYPTO("authenc");
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 4be0dd4373a9a2..024bff2344fcff 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -812,5 +812,6 @@ module_init(crypto_authenc_esn_module_init);
 module_exit(crypto_authenc_esn_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
 MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers");
+MODULE_ALIAS_CRYPTO("authencesn");
diff --git a/crypto/cbc.c b/crypto/cbc.c
index 61ac42e1e32bb7..780ee27b2d43d5 100644
--- a/crypto/cbc.c
+++ b/crypto/cbc.c
@@ -287,5 +287,6 @@ static void __exit crypto_cbc_module_exit(void)
 module_init(crypto_cbc_module_init);
 module_exit(crypto_cbc_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CBC block cipher algorithm");
+MODULE_ALIAS_CRYPTO("cbc");
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 647575b412815f..003bbbd21a2ba9 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -879,5 +879,6 @@ module_exit(crypto_ccm_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Counter with CBC MAC");
 MODULE_ALIAS_CRYPTO("ccm_base");
 MODULE_ALIAS_CRYPTO("rfc4309");
+MODULE_ALIAS_CRYPTO("ccm");
diff --git a/crypto/chainiv.c b/crypto/chainiv.c
index 9c294c8f9a0788..63c17d5992f79b 100644
--- a/crypto/chainiv.c
+++ b/crypto/chainiv.c
@@ -357,5 +357,6 @@ static void chainiv_module_exit(void)
 module_init(chainiv_module_init);
 module_exit(chainiv_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Chain IV Generator");
+MODULE_ALIAS_CRYPTO("chainiv");
diff --git a/crypto/cmac.c b/crypto/cmac.c
index 50880cf17fad70..7a8bfbd548f608 100644
--- a/crypto/cmac.c
+++ b/crypto/cmac.c
@@ -311,5 +311,6 @@ static void __exit crypto_cmac_module_exit(void)
 module_init(crypto_cmac_module_init);
 module_exit(crypto_cmac_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CMAC keyed hash algorithm");
+MODULE_ALIAS_CRYPTO("cmac");
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index e592c90abebb70..650afac10fd78e 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -953,5 +953,6 @@ static void __exit cryptd_exit(void)
 subsys_initcall(cryptd_init);
 module_exit(cryptd_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Software async crypto daemon");
+MODULE_ALIAS_CRYPTO("cryptd");
diff --git a/crypto/ctr.c b/crypto/ctr.c
index 3d81ff7e6b4894..2386f731395207 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -465,5 +465,6 @@ module_init(crypto_ctr_module_init);
 module_exit(crypto_ctr_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CTR Counter block mode");
 MODULE_ALIAS_CRYPTO("rfc3686");
+MODULE_ALIAS_CRYPTO("ctr");
diff --git a/crypto/cts.c b/crypto/cts.c
index 133f0874c95ecc..bd9405820e8ac5 100644
--- a/crypto/cts.c
+++ b/crypto/cts.c
@@ -349,5 +349,6 @@ static void __exit crypto_cts_module_exit(void)
 module_init(crypto_cts_module_init);
 module_exit(crypto_cts_module_exit);
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");
+MODULE_ALIAS_CRYPTO("cts");
diff --git a/crypto/ecb.c b/crypto/ecb.c
index 935cfef4aa8479..12011aff097136 100644
--- a/crypto/ecb.c
+++ b/crypto/ecb.c
@@ -183,5 +183,6 @@ static void __exit crypto_ecb_module_exit(void)
 module_init(crypto_ecb_module_init);
 module_exit(crypto_ecb_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("ECB block cipher algorithm");
+MODULE_ALIAS_CRYPTO("ecb");
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index bf7ab4a89493cd..f116fae766f816 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -265,5 +265,6 @@ static void __exit eseqiv_module_exit(void)
 module_init(eseqiv_module_init);
 module_exit(eseqiv_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Encrypted Sequence Number IV Generator");
+MODULE_ALIAS_CRYPTO("eseqiv");
diff --git a/crypto/gcm.c b/crypto/gcm.c
index aefb74a3f522ba..2e403f6138c14b 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -1442,5 +1442,6 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Galois/Counter Mode");
 MODULE_AUTHOR("Mikko Herranen <mh1@iki.fi>");
 MODULE_ALIAS_CRYPTO("gcm_base");
 MODULE_ALIAS_CRYPTO("rfc4106");
 MODULE_ALIAS_CRYPTO("rfc4543");
+MODULE_ALIAS_CRYPTO("gcm");
diff --git a/crypto/hmac.c b/crypto/hmac.c
index e392219ddc6195..72e38c098bb318 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -266,5 +266,6 @@ static void __exit hmac_module_exit(void)
 module_init(hmac_module_init);
 module_exit(hmac_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("HMAC hash algorithm");
+MODULE_ALIAS_CRYPTO("hmac");
diff --git a/crypto/lrw.c b/crypto/lrw.c
index ba42acc4deba80..6f9908a7ebcbe1 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -398,5 +398,6 @@ static void __exit crypto_module_exit(void)
 module_init(crypto_module_init);
 module_exit(crypto_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("LRW block cipher mode");
+MODULE_ALIAS_CRYPTO("lrw");
diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c
index b39fbd53010209..a8e870444ea9ce 100644
--- a/crypto/mcryptd.c
+++ b/crypto/mcryptd.c
@@ -701,5 +701,6 @@ static void __exit mcryptd_exit(void)
 subsys_initcall(mcryptd_init);
 module_exit(mcryptd_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Software async multibuffer crypto daemon");
+MODULE_ALIAS_CRYPTO("mcryptd");
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index d1b8bdfb58551e..f654965f09338d 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -293,5 +293,6 @@ static void __exit crypto_pcbc_module_exit(void)
 module_init(crypto_pcbc_module_init);
 module_exit(crypto_pcbc_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("PCBC block cipher algorithm");
+MODULE_ALIAS_CRYPTO("pcbc");
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 309d345ead9582..c305d4112735cd 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -563,5 +563,6 @@ module_init(pcrypt_init);
 module_exit(pcrypt_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
 MODULE_DESCRIPTION("Parallel crypto wrapper");
+MODULE_ALIAS_CRYPTO("pcrypt");
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index ee190fcedcd2e7..9daa854cc485b6 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -360,5 +360,6 @@ static void __exit seqiv_module_exit(void)
 module_init(seqiv_module_init);
 module_exit(seqiv_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Sequence Number IV Generator");
+MODULE_ALIAS_CRYPTO("seqiv");
diff --git a/crypto/vmac.c b/crypto/vmac.c
index d84c24bd7ff7bb..df76a816cfb22f 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -711,5 +711,6 @@ static void __exit vmac_module_exit(void)
 module_init(vmac_module_init);
 module_exit(vmac_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("VMAC hash algorithm");
+MODULE_ALIAS_CRYPTO("vmac");
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index a5fbdf3738cfd4..df90b332554cf4 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -284,5 +284,6 @@ static void __exit crypto_xcbc_module_exit(void)
 module_init(crypto_xcbc_module_init);
 module_exit(crypto_xcbc_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("XCBC keyed hash algorithm");
+MODULE_ALIAS_CRYPTO("xcbc");
diff --git a/crypto/xts.c b/crypto/xts.c
index ca1608f44cb566..f6fd43f100c8c6 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -360,5 +360,6 @@ static void __exit crypto_module_exit(void)
 module_init(crypto_module_init);
 module_exit(crypto_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("XTS block cipher mode");
+MODULE_ALIAS_CRYPTO("xts");

Vulnerable code: 	return try_then_request_module(__crypto_lookup_template(name), "%s",
				       name);
Fixed code: #include <linux/crypto.h>

MODULE_ALIAS_CRYPTO("fpu");
	return try_then_request_module(__crypto_lookup_template(name),
				       "crypto-%s", name);
MODULE_ALIAS_CRYPTO("authenc");
MODULE_ALIAS_CRYPTO("authencesn");
MODULE_ALIAS_CRYPTO("cbc");
MODULE_ALIAS_CRYPTO("ccm");
MODULE_ALIAS_CRYPTO("chainiv");
MODULE_ALIAS_CRYPTO("cmac");
MODULE_ALIAS_CRYPTO("cryptd");
MODULE_ALIAS_CRYPTO("ctr");
MODULE_ALIAS_CRYPTO("cts");
MODULE_ALIAS_CRYPTO("ecb");
MODULE_ALIAS_CRYPTO("eseqiv");
MODULE_ALIAS_CRYPTO("gcm");
MODULE_ALIAS_CRYPTO("hmac");
MODULE_ALIAS_CRYPTO("lrw");
MODULE_ALIAS_CRYPTO("mcryptd");
MODULE_ALIAS_CRYPTO("pcbc");
MODULE_ALIAS_CRYPTO("pcrypt");
MODULE_ALIAS_CRYPTO("seqiv");
MODULE_ALIAS_CRYPTO("vmac");
MODULE_ALIAS_CRYPTO("xcbc");
MODULE_ALIAS_CRYPTO("xts");