diff options
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | include/linux/digsig.h | 4 | ||||
-rw-r--r-- | include/linux/key.h | 3 | ||||
-rw-r--r-- | lib/Kconfig | 19 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | security/integrity/Kconfig | 4 | ||||
-rw-r--r-- | security/integrity/Makefile | 2 | ||||
-rw-r--r-- | security/integrity/integrity.h | 4 | ||||
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 6 | ||||
-rw-r--r-- | security/keys/encrypted-keys/masterkey_trusted.c | 4 | ||||
-rw-r--r-- | security/keys/gc.c | 4 | ||||
-rw-r--r-- | security/keys/keyring.c | 22 | ||||
-rw-r--r-- | security/keys/trusted.c | 4 | ||||
-rw-r--r-- | security/tomoyo/util.c | 6 |
14 files changed, 50 insertions, 36 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2a90101309d1..ece8935025e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5846,7 +5846,7 @@ F: drivers/mmc/host/sdhci-spear.c | |||
5846 | SECURITY SUBSYSTEM | 5846 | SECURITY SUBSYSTEM |
5847 | M: James Morris <jmorris@namei.org> | 5847 | M: James Morris <jmorris@namei.org> |
5848 | L: linux-security-module@vger.kernel.org (suggested Cc:) | 5848 | L: linux-security-module@vger.kernel.org (suggested Cc:) |
5849 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git | 5849 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git |
5850 | W: http://security.wiki.kernel.org/ | 5850 | W: http://security.wiki.kernel.org/ |
5851 | S: Supported | 5851 | S: Supported |
5852 | F: security/ | 5852 | F: security/ |
diff --git a/include/linux/digsig.h b/include/linux/digsig.h index efae755017d7..b01558b15814 100644 --- a/include/linux/digsig.h +++ b/include/linux/digsig.h | |||
@@ -46,7 +46,7 @@ struct signature_hdr { | |||
46 | char mpi[0]; | 46 | char mpi[0]; |
47 | } __packed; | 47 | } __packed; |
48 | 48 | ||
49 | #if defined(CONFIG_DIGSIG) || defined(CONFIG_DIGSIG_MODULE) | 49 | #if defined(CONFIG_SIGNATURE) || defined(CONFIG_SIGNATURE_MODULE) |
50 | 50 | ||
51 | int digsig_verify(struct key *keyring, const char *sig, int siglen, | 51 | int digsig_verify(struct key *keyring, const char *sig, int siglen, |
52 | const char *digest, int digestlen); | 52 | const char *digest, int digestlen); |
@@ -59,6 +59,6 @@ static inline int digsig_verify(struct key *keyring, const char *sig, | |||
59 | return -EOPNOTSUPP; | 59 | return -EOPNOTSUPP; |
60 | } | 60 | } |
61 | 61 | ||
62 | #endif /* CONFIG_DIGSIG */ | 62 | #endif /* CONFIG_SIGNATURE */ |
63 | 63 | ||
64 | #endif /* _DIGSIG_H */ | 64 | #endif /* _DIGSIG_H */ |
diff --git a/include/linux/key.h b/include/linux/key.h index 183a6af7715d..bfc014c57351 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -293,6 +293,9 @@ static inline bool key_is_instantiated(const struct key *key) | |||
293 | (rcu_dereference_protected((KEY)->payload.rcudata, \ | 293 | (rcu_dereference_protected((KEY)->payload.rcudata, \ |
294 | rwsem_is_locked(&((struct key *)(KEY))->sem))) | 294 | rwsem_is_locked(&((struct key *)(KEY))->sem))) |
295 | 295 | ||
296 | #define rcu_assign_keypointer(KEY, PAYLOAD) \ | ||
297 | (rcu_assign_pointer((KEY)->payload.rcudata, PAYLOAD)) | ||
298 | |||
296 | #ifdef CONFIG_SYSCTL | 299 | #ifdef CONFIG_SYSCTL |
297 | extern ctl_table key_sysctls[]; | 300 | extern ctl_table key_sysctls[]; |
298 | #endif | 301 | #endif |
diff --git a/lib/Kconfig b/lib/Kconfig index 201e1b33d721..169eb7c598e5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -286,25 +286,24 @@ config CORDIC | |||
286 | calculations are in fixed point. Module will be called cordic. | 286 | calculations are in fixed point. Module will be called cordic. |
287 | 287 | ||
288 | config MPILIB | 288 | config MPILIB |
289 | tristate "Multiprecision maths library" | 289 | tristate |
290 | help | 290 | help |
291 | Multiprecision maths library from GnuPG. | 291 | Multiprecision maths library from GnuPG. |
292 | It is used to implement RSA digital signature verification, | 292 | It is used to implement RSA digital signature verification, |
293 | which is used by IMA/EVM digital signature extension. | 293 | which is used by IMA/EVM digital signature extension. |
294 | 294 | ||
295 | config MPILIB_EXTRA | 295 | config MPILIB_EXTRA |
296 | bool "Multiprecision maths library - additional sources" | 296 | bool |
297 | depends on MPILIB | 297 | depends on MPILIB |
298 | help | 298 | help |
299 | Multiprecision maths library from GnuPG. | 299 | Additional sources of multiprecision maths library from GnuPG. |
300 | It is used to implement RSA digital signature verification, | 300 | This code is unnecessary for RSA digital signature verification, |
301 | which is used by IMA/EVM digital signature extension. | 301 | but can be compiled if needed. |
302 | This code in unnecessary for RSA digital signature verification, | ||
303 | and can be compiled if needed. | ||
304 | 302 | ||
305 | config DIGSIG | 303 | config SIGNATURE |
306 | tristate "In-kernel signature checker" | 304 | tristate |
307 | depends on KEYS | 305 | depends on KEYS && CRYPTO |
306 | select CRYPTO_SHA1 | ||
308 | select MPILIB | 307 | select MPILIB |
309 | help | 308 | help |
310 | Digital signature verification. Currently only RSA is supported. | 309 | Digital signature verification. Currently only RSA is supported. |
diff --git a/lib/Makefile b/lib/Makefile index dace162c7e1c..d71aae1b01b3 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -119,7 +119,7 @@ obj-$(CONFIG_CORDIC) += cordic.o | |||
119 | obj-$(CONFIG_DQL) += dynamic_queue_limits.o | 119 | obj-$(CONFIG_DQL) += dynamic_queue_limits.o |
120 | 120 | ||
121 | obj-$(CONFIG_MPILIB) += mpi/ | 121 | obj-$(CONFIG_MPILIB) += mpi/ |
122 | obj-$(CONFIG_DIGSIG) += digsig.o | 122 | obj-$(CONFIG_SIGNATURE) += digsig.o |
123 | 123 | ||
124 | hostprogs-y := gen_crc32table | 124 | hostprogs-y := gen_crc32table |
125 | clean-files := crc32table.h | 125 | clean-files := crc32table.h |
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index d384ea921482..5bd1cc1b4a54 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig | |||
@@ -3,11 +3,11 @@ config INTEGRITY | |||
3 | def_bool y | 3 | def_bool y |
4 | depends on IMA || EVM | 4 | depends on IMA || EVM |
5 | 5 | ||
6 | config INTEGRITY_DIGSIG | 6 | config INTEGRITY_SIGNATURE |
7 | boolean "Digital signature verification using multiple keyrings" | 7 | boolean "Digital signature verification using multiple keyrings" |
8 | depends on INTEGRITY && KEYS | 8 | depends on INTEGRITY && KEYS |
9 | default n | 9 | default n |
10 | select DIGSIG | 10 | select SIGNATURE |
11 | help | 11 | help |
12 | This option enables digital signature verification support | 12 | This option enables digital signature verification support |
13 | using multiple keyrings. It defines separate keyrings for each | 13 | using multiple keyrings. It defines separate keyrings for each |
diff --git a/security/integrity/Makefile b/security/integrity/Makefile index bece0563ee5e..d43799cc14f6 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_INTEGRITY) += integrity.o | 5 | obj-$(CONFIG_INTEGRITY) += integrity.o |
6 | obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o | 6 | obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o |
7 | 7 | ||
8 | integrity-y := iint.o | 8 | integrity-y := iint.o |
9 | 9 | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 4da6ba81d153..7a25ecec5aaa 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -51,7 +51,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); | |||
51 | #define INTEGRITY_KEYRING_IMA 2 | 51 | #define INTEGRITY_KEYRING_IMA 2 |
52 | #define INTEGRITY_KEYRING_MAX 3 | 52 | #define INTEGRITY_KEYRING_MAX 3 |
53 | 53 | ||
54 | #ifdef CONFIG_INTEGRITY_DIGSIG | 54 | #ifdef CONFIG_INTEGRITY_SIGNATURE |
55 | 55 | ||
56 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | 56 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, |
57 | const char *digest, int digestlen); | 57 | const char *digest, int digestlen); |
@@ -65,7 +65,7 @@ static inline int integrity_digsig_verify(const unsigned int id, | |||
65 | return -EOPNOTSUPP; | 65 | return -EOPNOTSUPP; |
66 | } | 66 | } |
67 | 67 | ||
68 | #endif /* CONFIG_INTEGRITY_DIGSIG */ | 68 | #endif /* CONFIG_INTEGRITY_SIGNATURE */ |
69 | 69 | ||
70 | /* set during initialization */ | 70 | /* set during initialization */ |
71 | extern int iint_initialized; | 71 | extern int iint_initialized; |
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 41144f71d615..2d1bb8af7696 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key, | |||
314 | goto error; | 314 | goto error; |
315 | 315 | ||
316 | down_read(&ukey->sem); | 316 | down_read(&ukey->sem); |
317 | upayload = rcu_dereference(ukey->payload.data); | 317 | upayload = ukey->payload.data; |
318 | *master_key = upayload->data; | 318 | *master_key = upayload->data; |
319 | *master_keylen = upayload->datalen; | 319 | *master_keylen = upayload->datalen; |
320 | error: | 320 | error: |
@@ -810,7 +810,7 @@ static int encrypted_instantiate(struct key *key, const void *data, | |||
810 | goto out; | 810 | goto out; |
811 | } | 811 | } |
812 | 812 | ||
813 | rcu_assign_pointer(key->payload.data, epayload); | 813 | rcu_assign_keypointer(key, epayload); |
814 | out: | 814 | out: |
815 | kfree(datablob); | 815 | kfree(datablob); |
816 | return ret; | 816 | return ret; |
@@ -874,7 +874,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
874 | memcpy(new_epayload->payload_data, epayload->payload_data, | 874 | memcpy(new_epayload->payload_data, epayload->payload_data, |
875 | epayload->payload_datalen); | 875 | epayload->payload_datalen); |
876 | 876 | ||
877 | rcu_assign_pointer(key->payload.data, new_epayload); | 877 | rcu_assign_keypointer(key, new_epayload); |
878 | call_rcu(&epayload->rcu, encrypted_rcu_free); | 878 | call_rcu(&epayload->rcu, encrypted_rcu_free); |
879 | out: | 879 | out: |
880 | kfree(buf); | 880 | kfree(buf); |
diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c index df87272e3f51..013f7e5d3a2f 100644 --- a/security/keys/encrypted-keys/masterkey_trusted.c +++ b/security/keys/encrypted-keys/masterkey_trusted.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <keys/trusted-type.h> | 20 | #include <keys/trusted-type.h> |
21 | #include <keys/encrypted-type.h> | ||
22 | #include "encrypted.h" | ||
21 | 23 | ||
22 | /* | 24 | /* |
23 | * request_trusted_key - request the trusted key | 25 | * request_trusted_key - request the trusted key |
@@ -37,7 +39,7 @@ struct key *request_trusted_key(const char *trusted_desc, | |||
37 | goto error; | 39 | goto error; |
38 | 40 | ||
39 | down_read(&tkey->sem); | 41 | down_read(&tkey->sem); |
40 | tpayload = rcu_dereference(tkey->payload.data); | 42 | tpayload = tkey->payload.data; |
41 | *master_key = tpayload->key; | 43 | *master_key = tpayload->key; |
42 | *master_keylen = tpayload->key_len; | 44 | *master_keylen = tpayload->key_len; |
43 | error: | 45 | error: |
diff --git a/security/keys/gc.c b/security/keys/gc.c index bf4d8da5a795..a42b45531aac 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c | |||
@@ -145,7 +145,9 @@ static void key_gc_keyring(struct key *keyring, time_t limit) | |||
145 | if (!klist) | 145 | if (!klist) |
146 | goto unlock_dont_gc; | 146 | goto unlock_dont_gc; |
147 | 147 | ||
148 | for (loop = klist->nkeys - 1; loop >= 0; loop--) { | 148 | loop = klist->nkeys; |
149 | smp_rmb(); | ||
150 | for (loop--; loop >= 0; loop--) { | ||
149 | key = klist->keys[loop]; | 151 | key = klist->keys[loop]; |
150 | if (test_bit(KEY_FLAG_DEAD, &key->flags) || | 152 | if (test_bit(KEY_FLAG_DEAD, &key->flags) || |
151 | (key->expiry > 0 && key->expiry <= limit)) | 153 | (key->expiry > 0 && key->expiry <= limit)) |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 37a7f3b28852..d605f75292e4 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -319,7 +319,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
319 | struct key *keyring, *key; | 319 | struct key *keyring, *key; |
320 | key_ref_t key_ref; | 320 | key_ref_t key_ref; |
321 | long err; | 321 | long err; |
322 | int sp, kix; | 322 | int sp, nkeys, kix; |
323 | 323 | ||
324 | keyring = key_ref_to_ptr(keyring_ref); | 324 | keyring = key_ref_to_ptr(keyring_ref); |
325 | possessed = is_key_possessed(keyring_ref); | 325 | possessed = is_key_possessed(keyring_ref); |
@@ -380,7 +380,9 @@ descend: | |||
380 | goto not_this_keyring; | 380 | goto not_this_keyring; |
381 | 381 | ||
382 | /* iterate through the keys in this keyring first */ | 382 | /* iterate through the keys in this keyring first */ |
383 | for (kix = 0; kix < keylist->nkeys; kix++) { | 383 | nkeys = keylist->nkeys; |
384 | smp_rmb(); | ||
385 | for (kix = 0; kix < nkeys; kix++) { | ||
384 | key = keylist->keys[kix]; | 386 | key = keylist->keys[kix]; |
385 | kflags = key->flags; | 387 | kflags = key->flags; |
386 | 388 | ||
@@ -421,7 +423,9 @@ descend: | |||
421 | /* search through the keyrings nested in this one */ | 423 | /* search through the keyrings nested in this one */ |
422 | kix = 0; | 424 | kix = 0; |
423 | ascend: | 425 | ascend: |
424 | for (; kix < keylist->nkeys; kix++) { | 426 | nkeys = keylist->nkeys; |
427 | smp_rmb(); | ||
428 | for (; kix < nkeys; kix++) { | ||
425 | key = keylist->keys[kix]; | 429 | key = keylist->keys[kix]; |
426 | if (key->type != &key_type_keyring) | 430 | if (key->type != &key_type_keyring) |
427 | continue; | 431 | continue; |
@@ -515,7 +519,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref, | |||
515 | struct keyring_list *klist; | 519 | struct keyring_list *klist; |
516 | unsigned long possessed; | 520 | unsigned long possessed; |
517 | struct key *keyring, *key; | 521 | struct key *keyring, *key; |
518 | int loop; | 522 | int nkeys, loop; |
519 | 523 | ||
520 | keyring = key_ref_to_ptr(keyring_ref); | 524 | keyring = key_ref_to_ptr(keyring_ref); |
521 | possessed = is_key_possessed(keyring_ref); | 525 | possessed = is_key_possessed(keyring_ref); |
@@ -524,7 +528,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref, | |||
524 | 528 | ||
525 | klist = rcu_dereference(keyring->payload.subscriptions); | 529 | klist = rcu_dereference(keyring->payload.subscriptions); |
526 | if (klist) { | 530 | if (klist) { |
527 | for (loop = 0; loop < klist->nkeys; loop++) { | 531 | nkeys = klist->nkeys; |
532 | smp_rmb(); | ||
533 | for (loop = 0; loop < nkeys ; loop++) { | ||
528 | key = klist->keys[loop]; | 534 | key = klist->keys[loop]; |
529 | 535 | ||
530 | if (key->type == ktype && | 536 | if (key->type == ktype && |
@@ -622,7 +628,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B) | |||
622 | 628 | ||
623 | struct keyring_list *keylist; | 629 | struct keyring_list *keylist; |
624 | struct key *subtree, *key; | 630 | struct key *subtree, *key; |
625 | int sp, kix, ret; | 631 | int sp, nkeys, kix, ret; |
626 | 632 | ||
627 | rcu_read_lock(); | 633 | rcu_read_lock(); |
628 | 634 | ||
@@ -645,7 +651,9 @@ descend: | |||
645 | 651 | ||
646 | ascend: | 652 | ascend: |
647 | /* iterate through the remaining keys in this keyring */ | 653 | /* iterate through the remaining keys in this keyring */ |
648 | for (; kix < keylist->nkeys; kix++) { | 654 | nkeys = keylist->nkeys; |
655 | smp_rmb(); | ||
656 | for (; kix < nkeys; kix++) { | ||
649 | key = keylist->keys[kix]; | 657 | key = keylist->keys[kix]; |
650 | 658 | ||
651 | if (key == A) | 659 | if (key == A) |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 0ed5fdf238a2..2d5d041f2049 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -993,7 +993,7 @@ out: | |||
993 | kfree(datablob); | 993 | kfree(datablob); |
994 | kfree(options); | 994 | kfree(options); |
995 | if (!ret) | 995 | if (!ret) |
996 | rcu_assign_pointer(key->payload.data, payload); | 996 | rcu_assign_keypointer(key, payload); |
997 | else | 997 | else |
998 | kfree(payload); | 998 | kfree(payload); |
999 | return ret; | 999 | return ret; |
@@ -1067,7 +1067,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen) | |||
1067 | goto out; | 1067 | goto out; |
1068 | } | 1068 | } |
1069 | } | 1069 | } |
1070 | rcu_assign_pointer(key->payload.data, new_p); | 1070 | rcu_assign_keypointer(key, new_p); |
1071 | call_rcu(&p->rcu, trusted_rcu_free); | 1071 | call_rcu(&p->rcu, trusted_rcu_free); |
1072 | out: | 1072 | out: |
1073 | kfree(datablob); | 1073 | kfree(datablob); |
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 4a9b4b2eb755..867558c98334 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c | |||
@@ -492,13 +492,13 @@ static bool tomoyo_correct_word2(const char *string, size_t len) | |||
492 | if (d < '0' || d > '7' || e < '0' || e > '7') | 492 | if (d < '0' || d > '7' || e < '0' || e > '7') |
493 | break; | 493 | break; |
494 | c = tomoyo_make_byte(c, d, e); | 494 | c = tomoyo_make_byte(c, d, e); |
495 | if (tomoyo_invalid(c)) | 495 | if (c <= ' ' || c >= 127) |
496 | continue; /* pattern is not \000 */ | 496 | continue; |
497 | } | 497 | } |
498 | goto out; | 498 | goto out; |
499 | } else if (in_repetition && c == '/') { | 499 | } else if (in_repetition && c == '/') { |
500 | goto out; | 500 | goto out; |
501 | } else if (tomoyo_invalid(c)) { | 501 | } else if (c <= ' ' || c >= 127) { |
502 | goto out; | 502 | goto out; |
503 | } | 503 | } |
504 | } | 504 | } |