aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-21 22:46:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-21 22:46:00 -0500
commit78dc53c422172a317adb0776dfb687057ffa28b7 (patch)
tree7c5d15da75d769d01f6a992c24c3490b3867d5b2 /security/keys/key.c
parent3eaded86ac3e7f00fb3eeb8162d89e9a34e42fb0 (diff)
parent62fe318256befbd1b4a6765e71d9c997f768fe79 (diff)
Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "In this patchset, we finally get an SELinux update, with Paul Moore taking over as maintainer of that code. Also a significant update for the Keys subsystem, as well as maintenance updates to Smack, IMA, TPM, and Apparmor" and since I wanted to know more about the updates to key handling, here's the explanation from David Howells on that: "Okay. There are a number of separate bits. I'll go over the big bits and the odd important other bit, most of the smaller bits are just fixes and cleanups. If you want the small bits accounting for, I can do that too. (1) Keyring capacity expansion. KEYS: Consolidate the concept of an 'index key' for key access KEYS: Introduce a search context structure KEYS: Search for auth-key by name rather than target key ID Add a generic associative array implementation. KEYS: Expand the capacity of a keyring Several of the patches are providing an expansion of the capacity of a keyring. Currently, the maximum size of a keyring payload is one page. Subtract a small header and then divide up into pointers, that only gives you ~500 pointers on an x86_64 box. However, since the NFS idmapper uses a keyring to store ID mapping data, that has proven to be insufficient to the cause. Whatever data structure I use to handle the keyring payload, it can only store pointers to keys, not the keys themselves because several keyrings may point to a single key. This precludes inserting, say, and rb_node struct into the key struct for this purpose. I could make an rbtree of records such that each record has an rb_node and a key pointer, but that would use four words of space per key stored in the keyring. It would, however, be able to use much existing code. I selected instead a non-rebalancing radix-tree type approach as that could have a better space-used/key-pointer ratio. I could have used the radix tree implementation that we already have and insert keys into it by their serial numbers, but that means any sort of search must iterate over the whole radix tree. Further, its nodes are a bit on the capacious side for what I want - especially given that key serial numbers are randomly allocated, thus leaving a lot of empty space in the tree. So what I have is an associative array that internally is a radix-tree with 16 pointers per node where the index key is constructed from the key type pointer and the key description. This means that an exact lookup by type+description is very fast as this tells us how to navigate directly to the target key. I made the data structure general in lib/assoc_array.c as far as it is concerned, its index key is just a sequence of bits that leads to a pointer. It's possible that someone else will be able to make use of it also. FS-Cache might, for example. (2) Mark keys as 'trusted' and keyrings as 'trusted only'. KEYS: verify a certificate is signed by a 'trusted' key KEYS: Make the system 'trusted' keyring viewable by userspace KEYS: Add a 'trusted' flag and a 'trusted only' flag KEYS: Separate the kernel signature checking keyring from module signing These patches allow keys carrying asymmetric public keys to be marked as being 'trusted' and allow keyrings to be marked as only permitting the addition or linkage of trusted keys. Keys loaded from hardware during kernel boot or compiled into the kernel during build are marked as being trusted automatically. New keys can be loaded at runtime with add_key(). They are checked against the system keyring contents and if their signatures can be validated with keys that are already marked trusted, then they are marked trusted also and can thus be added into the master keyring. Patches from Mimi Zohar make this usable with the IMA keyrings also. (3) Remove the date checks on the key used to validate a module signature. X.509: Remove certificate date checks It's not reasonable to reject a signature just because the key that it was generated with is no longer valid datewise - especially if the kernel hasn't yet managed to set the system clock when the first module is loaded - so just remove those checks. (4) Make it simpler to deal with additional X.509 being loaded into the kernel. KEYS: Load *.x509 files into kernel keyring KEYS: Have make canonicalise the paths of the X.509 certs better to deduplicate The builder of the kernel now just places files with the extension ".x509" into the kernel source or build trees and they're concatenated by the kernel build and stuffed into the appropriate section. (5) Add support for userspace kerberos to use keyrings. KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches KEYS: Implement a big key type that can save to tmpfs Fedora went to, by default, storing kerberos tickets and tokens in tmpfs. We looked at storing it in keyrings instead as that confers certain advantages such as tickets being automatically deleted after a certain amount of time and the ability for the kernel to get at these tokens more easily. To make this work, two things were needed: (a) A way for the tickets to persist beyond the lifetime of all a user's sessions so that cron-driven processes can still use them. The problem is that a user's session keyrings are deleted when the session that spawned them logs out and the user's user keyring is deleted when the UID is deleted (typically when the last log out happens), so neither of these places is suitable. I've added a system keyring into which a 'persistent' keyring is created for each UID on request. Each time a user requests their persistent keyring, the expiry time on it is set anew. If the user doesn't ask for it for, say, three days, the keyring is automatically expired and garbage collected using the existing gc. All the kerberos tokens it held are then also gc'd. (b) A key type that can hold really big tickets (up to 1MB in size). The problem is that Active Directory can return huge tickets with lots of auxiliary data attached. We don't, however, want to eat up huge tracts of unswappable kernel space for this, so if the ticket is greater than a certain size, we create a swappable shmem file and dump the contents in there and just live with the fact we then have an inode and a dentry overhead. If the ticket is smaller than that, we slap it in a kmalloc()'d buffer" * 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (121 commits) KEYS: Fix keyring content gc scanner KEYS: Fix error handling in big_key instantiation KEYS: Fix UID check in keyctl_get_persistent() KEYS: The RSA public key algorithm needs to select MPILIB ima: define '_ima' as a builtin 'trusted' keyring ima: extend the measurement list to include the file signature kernel/system_certificate.S: use real contents instead of macro GLOBAL() KEYS: fix error return code in big_key_instantiate() KEYS: Fix keyring quota misaccounting on key replacement and unlink KEYS: Fix a race between negating a key and reading the error set KEYS: Make BIG_KEYS boolean apparmor: remove the "task" arg from may_change_ptraced_domain() apparmor: remove parent task info from audit logging apparmor: remove tsk field from the apparmor_audit_struct apparmor: fix capability to not use the current task, during reporting Smack: Ptrace access check mode ima: provide hash algo info in the xattr ima: enable support for larger default filedata hash algorithms ima: define kernel parameter 'ima_template=' to change configured default ima: add Kconfig default measurement list template ...
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c102
1 files changed, 56 insertions, 46 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 8fb7c7bd4657..55d110f0aced 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -242,8 +242,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
242 } 242 }
243 } 243 }
244 244
245 desclen = strlen(desc) + 1; 245 desclen = strlen(desc);
246 quotalen = desclen + type->def_datalen; 246 quotalen = desclen + 1 + type->def_datalen;
247 247
248 /* get hold of the key tracking for this user */ 248 /* get hold of the key tracking for this user */
249 user = key_user_lookup(uid); 249 user = key_user_lookup(uid);
@@ -277,7 +277,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
277 goto no_memory_2; 277 goto no_memory_2;
278 278
279 if (desc) { 279 if (desc) {
280 key->description = kmemdup(desc, desclen, GFP_KERNEL); 280 key->index_key.desc_len = desclen;
281 key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL);
281 if (!key->description) 282 if (!key->description)
282 goto no_memory_3; 283 goto no_memory_3;
283 } 284 }
@@ -285,7 +286,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
285 atomic_set(&key->usage, 1); 286 atomic_set(&key->usage, 1);
286 init_rwsem(&key->sem); 287 init_rwsem(&key->sem);
287 lockdep_set_class(&key->sem, &type->lock_class); 288 lockdep_set_class(&key->sem, &type->lock_class);
288 key->type = type; 289 key->index_key.type = type;
289 key->user = user; 290 key->user = user;
290 key->quotalen = quotalen; 291 key->quotalen = quotalen;
291 key->datalen = type->def_datalen; 292 key->datalen = type->def_datalen;
@@ -299,6 +300,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
299 300
300 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 301 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
301 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
303 if (flags & KEY_ALLOC_TRUSTED)
304 key->flags |= 1 << KEY_FLAG_TRUSTED;
302 305
303 memset(&key->type_data, 0, sizeof(key->type_data)); 306 memset(&key->type_data, 0, sizeof(key->type_data));
304 307
@@ -408,7 +411,7 @@ static int __key_instantiate_and_link(struct key *key,
408 struct key_preparsed_payload *prep, 411 struct key_preparsed_payload *prep,
409 struct key *keyring, 412 struct key *keyring,
410 struct key *authkey, 413 struct key *authkey,
411 unsigned long *_prealloc) 414 struct assoc_array_edit **_edit)
412{ 415{
413 int ret, awaken; 416 int ret, awaken;
414 417
@@ -435,7 +438,7 @@ static int __key_instantiate_and_link(struct key *key,
435 438
436 /* and link it into the destination keyring */ 439 /* and link it into the destination keyring */
437 if (keyring) 440 if (keyring)
438 __key_link(keyring, key, _prealloc); 441 __key_link(key, _edit);
439 442
440 /* disable the authorisation key */ 443 /* disable the authorisation key */
441 if (authkey) 444 if (authkey)
@@ -475,7 +478,7 @@ int key_instantiate_and_link(struct key *key,
475 struct key *authkey) 478 struct key *authkey)
476{ 479{
477 struct key_preparsed_payload prep; 480 struct key_preparsed_payload prep;
478 unsigned long prealloc; 481 struct assoc_array_edit *edit;
479 int ret; 482 int ret;
480 483
481 memset(&prep, 0, sizeof(prep)); 484 memset(&prep, 0, sizeof(prep));
@@ -489,17 +492,15 @@ int key_instantiate_and_link(struct key *key,
489 } 492 }
490 493
491 if (keyring) { 494 if (keyring) {
492 ret = __key_link_begin(keyring, key->type, key->description, 495 ret = __key_link_begin(keyring, &key->index_key, &edit);
493 &prealloc);
494 if (ret < 0) 496 if (ret < 0)
495 goto error_free_preparse; 497 goto error_free_preparse;
496 } 498 }
497 499
498 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, 500 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
499 &prealloc);
500 501
501 if (keyring) 502 if (keyring)
502 __key_link_end(keyring, key->type, prealloc); 503 __key_link_end(keyring, &key->index_key, edit);
503 504
504error_free_preparse: 505error_free_preparse:
505 if (key->type->preparse) 506 if (key->type->preparse)
@@ -537,7 +538,7 @@ int key_reject_and_link(struct key *key,
537 struct key *keyring, 538 struct key *keyring,
538 struct key *authkey) 539 struct key *authkey)
539{ 540{
540 unsigned long prealloc; 541 struct assoc_array_edit *edit;
541 struct timespec now; 542 struct timespec now;
542 int ret, awaken, link_ret = 0; 543 int ret, awaken, link_ret = 0;
543 544
@@ -548,8 +549,7 @@ int key_reject_and_link(struct key *key,
548 ret = -EBUSY; 549 ret = -EBUSY;
549 550
550 if (keyring) 551 if (keyring)
551 link_ret = __key_link_begin(keyring, key->type, 552 link_ret = __key_link_begin(keyring, &key->index_key, &edit);
552 key->description, &prealloc);
553 553
554 mutex_lock(&key_construction_mutex); 554 mutex_lock(&key_construction_mutex);
555 555
@@ -557,9 +557,10 @@ int key_reject_and_link(struct key *key,
557 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 557 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
558 /* mark the key as being negatively instantiated */ 558 /* mark the key as being negatively instantiated */
559 atomic_inc(&key->user->nikeys); 559 atomic_inc(&key->user->nikeys);
560 key->type_data.reject_error = -error;
561 smp_wmb();
560 set_bit(KEY_FLAG_NEGATIVE, &key->flags); 562 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
561 set_bit(KEY_FLAG_INSTANTIATED, &key->flags); 563 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
562 key->type_data.reject_error = -error;
563 now = current_kernel_time(); 564 now = current_kernel_time();
564 key->expiry = now.tv_sec + timeout; 565 key->expiry = now.tv_sec + timeout;
565 key_schedule_gc(key->expiry + key_gc_delay); 566 key_schedule_gc(key->expiry + key_gc_delay);
@@ -571,7 +572,7 @@ int key_reject_and_link(struct key *key,
571 572
572 /* and link it into the destination keyring */ 573 /* and link it into the destination keyring */
573 if (keyring && link_ret == 0) 574 if (keyring && link_ret == 0)
574 __key_link(keyring, key, &prealloc); 575 __key_link(key, &edit);
575 576
576 /* disable the authorisation key */ 577 /* disable the authorisation key */
577 if (authkey) 578 if (authkey)
@@ -581,7 +582,7 @@ int key_reject_and_link(struct key *key,
581 mutex_unlock(&key_construction_mutex); 582 mutex_unlock(&key_construction_mutex);
582 583
583 if (keyring) 584 if (keyring)
584 __key_link_end(keyring, key->type, prealloc); 585 __key_link_end(keyring, &key->index_key, edit);
585 586
586 /* wake up anyone waiting for a key to be constructed */ 587 /* wake up anyone waiting for a key to be constructed */
587 if (awaken) 588 if (awaken)
@@ -645,7 +646,7 @@ found:
645 /* this races with key_put(), but that doesn't matter since key_put() 646 /* this races with key_put(), but that doesn't matter since key_put()
646 * doesn't actually change the key 647 * doesn't actually change the key
647 */ 648 */
648 atomic_inc(&key->usage); 649 __key_get(key);
649 650
650error: 651error:
651 spin_unlock(&key_serial_lock); 652 spin_unlock(&key_serial_lock);
@@ -780,25 +781,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
780 key_perm_t perm, 781 key_perm_t perm,
781 unsigned long flags) 782 unsigned long flags)
782{ 783{
783 unsigned long prealloc; 784 struct keyring_index_key index_key = {
785 .description = description,
786 };
784 struct key_preparsed_payload prep; 787 struct key_preparsed_payload prep;
788 struct assoc_array_edit *edit;
785 const struct cred *cred = current_cred(); 789 const struct cred *cred = current_cred();
786 struct key_type *ktype;
787 struct key *keyring, *key = NULL; 790 struct key *keyring, *key = NULL;
788 key_ref_t key_ref; 791 key_ref_t key_ref;
789 int ret; 792 int ret;
790 793
791 /* look up the key type to see if it's one of the registered kernel 794 /* look up the key type to see if it's one of the registered kernel
792 * types */ 795 * types */
793 ktype = key_type_lookup(type); 796 index_key.type = key_type_lookup(type);
794 if (IS_ERR(ktype)) { 797 if (IS_ERR(index_key.type)) {
795 key_ref = ERR_PTR(-ENODEV); 798 key_ref = ERR_PTR(-ENODEV);
796 goto error; 799 goto error;
797 } 800 }
798 801
799 key_ref = ERR_PTR(-EINVAL); 802 key_ref = ERR_PTR(-EINVAL);
800 if (!ktype->match || !ktype->instantiate || 803 if (!index_key.type->match || !index_key.type->instantiate ||
801 (!description && !ktype->preparse)) 804 (!index_key.description && !index_key.type->preparse))
802 goto error_put_type; 805 goto error_put_type;
803 806
804 keyring = key_ref_to_ptr(keyring_ref); 807 keyring = key_ref_to_ptr(keyring_ref);
@@ -812,21 +815,28 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
812 memset(&prep, 0, sizeof(prep)); 815 memset(&prep, 0, sizeof(prep));
813 prep.data = payload; 816 prep.data = payload;
814 prep.datalen = plen; 817 prep.datalen = plen;
815 prep.quotalen = ktype->def_datalen; 818 prep.quotalen = index_key.type->def_datalen;
816 if (ktype->preparse) { 819 prep.trusted = flags & KEY_ALLOC_TRUSTED;
817 ret = ktype->preparse(&prep); 820 if (index_key.type->preparse) {
821 ret = index_key.type->preparse(&prep);
818 if (ret < 0) { 822 if (ret < 0) {
819 key_ref = ERR_PTR(ret); 823 key_ref = ERR_PTR(ret);
820 goto error_put_type; 824 goto error_put_type;
821 } 825 }
822 if (!description) 826 if (!index_key.description)
823 description = prep.description; 827 index_key.description = prep.description;
824 key_ref = ERR_PTR(-EINVAL); 828 key_ref = ERR_PTR(-EINVAL);
825 if (!description) 829 if (!index_key.description)
826 goto error_free_prep; 830 goto error_free_prep;
827 } 831 }
832 index_key.desc_len = strlen(index_key.description);
833
834 key_ref = ERR_PTR(-EPERM);
835 if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags))
836 goto error_free_prep;
837 flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0;
828 838
829 ret = __key_link_begin(keyring, ktype, description, &prealloc); 839 ret = __key_link_begin(keyring, &index_key, &edit);
830 if (ret < 0) { 840 if (ret < 0) {
831 key_ref = ERR_PTR(ret); 841 key_ref = ERR_PTR(ret);
832 goto error_free_prep; 842 goto error_free_prep;
@@ -844,10 +854,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
844 * key of the same type and description in the destination keyring and 854 * key of the same type and description in the destination keyring and
845 * update that instead if possible 855 * update that instead if possible
846 */ 856 */
847 if (ktype->update) { 857 if (index_key.type->update) {
848 key_ref = __keyring_search_one(keyring_ref, ktype, description, 858 key_ref = find_key_to_update(keyring_ref, &index_key);
849 0); 859 if (key_ref)
850 if (!IS_ERR(key_ref))
851 goto found_matching_key; 860 goto found_matching_key;
852 } 861 }
853 862
@@ -856,23 +865,24 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
856 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 865 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
857 perm |= KEY_USR_VIEW; 866 perm |= KEY_USR_VIEW;
858 867
859 if (ktype->read) 868 if (index_key.type->read)
860 perm |= KEY_POS_READ; 869 perm |= KEY_POS_READ;
861 870
862 if (ktype == &key_type_keyring || ktype->update) 871 if (index_key.type == &key_type_keyring ||
872 index_key.type->update)
863 perm |= KEY_POS_WRITE; 873 perm |= KEY_POS_WRITE;
864 } 874 }
865 875
866 /* allocate a new key */ 876 /* allocate a new key */
867 key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred, 877 key = key_alloc(index_key.type, index_key.description,
868 perm, flags); 878 cred->fsuid, cred->fsgid, cred, perm, flags);
869 if (IS_ERR(key)) { 879 if (IS_ERR(key)) {
870 key_ref = ERR_CAST(key); 880 key_ref = ERR_CAST(key);
871 goto error_link_end; 881 goto error_link_end;
872 } 882 }
873 883
874 /* instantiate it and link it into the target keyring */ 884 /* instantiate it and link it into the target keyring */
875 ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc); 885 ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &edit);
876 if (ret < 0) { 886 if (ret < 0) {
877 key_put(key); 887 key_put(key);
878 key_ref = ERR_PTR(ret); 888 key_ref = ERR_PTR(ret);
@@ -882,12 +892,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
882 key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 892 key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
883 893
884error_link_end: 894error_link_end:
885 __key_link_end(keyring, ktype, prealloc); 895 __key_link_end(keyring, &index_key, edit);
886error_free_prep: 896error_free_prep:
887 if (ktype->preparse) 897 if (index_key.type->preparse)
888 ktype->free_preparse(&prep); 898 index_key.type->free_preparse(&prep);
889error_put_type: 899error_put_type:
890 key_type_put(ktype); 900 key_type_put(index_key.type);
891error: 901error:
892 return key_ref; 902 return key_ref;
893 903
@@ -895,7 +905,7 @@ error:
895 /* we found a matching key, so we're going to try to update it 905 /* we found a matching key, so we're going to try to update it
896 * - we can drop the locks first as we have the key pinned 906 * - we can drop the locks first as we have the key pinned
897 */ 907 */
898 __key_link_end(keyring, ktype, prealloc); 908 __key_link_end(keyring, &index_key, edit);
899 909
900 key_ref = __key_update(key_ref, &prep); 910 key_ref = __key_update(key_ref, &prep);
901 goto error_free_prep; 911 goto error_free_prep;