aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2005-06-24 01:00:56 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:05:19 -0400
commit3e30148c3d524a9c1c63ca28261bc24c457eb07a (patch)
treea2fcc46cc11fe871ad976c07476d934a07313576 /security/keys/keyctl.c
parent8589b4e00e352f983259140f25a262d973be6bc5 (diff)
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes: (1) There's a new special key type called ".request_key_auth". This is an authorisation key for when one process requests a key and another process is started to construct it. This type of key cannot be created by the user; nor can it be requested by kernel services. Authorisation keys hold two references: (a) Each refers to a key being constructed. When the key being constructed is instantiated the authorisation key is revoked, rendering it of no further use. (b) The "authorising process". This is either: (i) the process that called request_key(), or: (ii) if the process that called request_key() itself had an authorisation key in its session keyring, then the authorising process referred to by that authorisation key will also be referred to by the new authorisation key. This means that the process that initiated a chain of key requests will authorise the lot of them, and will, by default, wind up with the keys obtained from them in its keyrings. (2) request_key() creates an authorisation key which is then passed to /sbin/request-key in as part of a new session keyring. (3) When request_key() is searching for a key to hand back to the caller, if it comes across an authorisation key in the session keyring of the calling process, it will also search the keyrings of the process specified therein and it will use the specified process's credentials (fsuid, fsgid, groups) to do that rather than the calling process's credentials. This allows a process started by /sbin/request-key to find keys belonging to the authorising process. (4) A key can be read, even if the process executing KEYCTL_READ doesn't have direct read or search permission if that key is contained within the keyrings of a process specified by an authorisation key found within the calling process's session keyring, and is searchable using the credentials of the authorising process. This allows a process started by /sbin/request-key to read keys belonging to the authorising process. (5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or KEYCTL_NEGATE will specify a keyring of the authorising process, rather than the process doing the instantiation. (6) One of the process keyrings can be nominated as the default to which request_key() should attach new keys if not otherwise specified. This is done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_* constants. The current setting can also be read using this call. (7) request_key() is partially interruptible. If it is waiting for another process to finish constructing a key, it can be interrupted. This permits a request-key cycle to be broken without recourse to rebooting. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c176
1 files changed, 118 insertions, 58 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cedb7326de29..fea262860ea0 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1,6 +1,6 @@
1/* keyctl.c: userspace keyctl operations 1/* keyctl.c: userspace keyctl operations
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -49,6 +49,13 @@ asmlinkage long sys_add_key(const char __user *_type,
49 goto error; 49 goto error;
50 type[31] = '\0'; 50 type[31] = '\0';
51 51
52 if (!type[0])
53 goto error;
54
55 ret = -EPERM;
56 if (type[0] == '.')
57 goto error;
58
52 ret = -EFAULT; 59 ret = -EFAULT;
53 dlen = strnlen_user(_description, PAGE_SIZE - 1); 60 dlen = strnlen_user(_description, PAGE_SIZE - 1);
54 if (dlen <= 0) 61 if (dlen <= 0)
@@ -82,7 +89,7 @@ asmlinkage long sys_add_key(const char __user *_type,
82 } 89 }
83 90
84 /* find the target keyring (which must be writable) */ 91 /* find the target keyring (which must be writable) */
85 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 92 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
86 if (IS_ERR(keyring)) { 93 if (IS_ERR(keyring)) {
87 ret = PTR_ERR(keyring); 94 ret = PTR_ERR(keyring);
88 goto error3; 95 goto error3;
@@ -181,7 +188,7 @@ asmlinkage long sys_request_key(const char __user *_type,
181 /* get the destination keyring if specified */ 188 /* get the destination keyring if specified */
182 dest = NULL; 189 dest = NULL;
183 if (destringid) { 190 if (destringid) {
184 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 191 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
185 if (IS_ERR(dest)) { 192 if (IS_ERR(dest)) {
186 ret = PTR_ERR(dest); 193 ret = PTR_ERR(dest);
187 goto error3; 194 goto error3;
@@ -196,23 +203,15 @@ asmlinkage long sys_request_key(const char __user *_type,
196 } 203 }
197 204
198 /* do the search */ 205 /* do the search */
199 key = request_key(ktype, description, callout_info); 206 key = request_key_and_link(ktype, description, callout_info, dest);
200 if (IS_ERR(key)) { 207 if (IS_ERR(key)) {
201 ret = PTR_ERR(key); 208 ret = PTR_ERR(key);
202 goto error5; 209 goto error5;
203 } 210 }
204 211
205 /* link the resulting key to the destination keyring */
206 if (dest) {
207 ret = key_link(dest, key);
208 if (ret < 0)
209 goto error6;
210 }
211
212 ret = key->serial; 212 ret = key->serial;
213 213
214 error6: 214 key_put(key);
215 key_put(key);
216 error5: 215 error5:
217 key_type_put(ktype); 216 key_type_put(ktype);
218 error4: 217 error4:
@@ -237,7 +236,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
237 struct key *key; 236 struct key *key;
238 long ret; 237 long ret;
239 238
240 key = lookup_user_key(id, create, 0, KEY_SEARCH); 239 key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
241 if (IS_ERR(key)) { 240 if (IS_ERR(key)) {
242 ret = PTR_ERR(key); 241 ret = PTR_ERR(key);
243 goto error; 242 goto error;
@@ -324,7 +323,7 @@ long keyctl_update_key(key_serial_t id,
324 } 323 }
325 324
326 /* find the target key (which must be writable) */ 325 /* find the target key (which must be writable) */
327 key = lookup_user_key(id, 0, 0, KEY_WRITE); 326 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
328 if (IS_ERR(key)) { 327 if (IS_ERR(key)) {
329 ret = PTR_ERR(key); 328 ret = PTR_ERR(key);
330 goto error2; 329 goto error2;
@@ -352,7 +351,7 @@ long keyctl_revoke_key(key_serial_t id)
352 struct key *key; 351 struct key *key;
353 long ret; 352 long ret;
354 353
355 key = lookup_user_key(id, 0, 0, KEY_WRITE); 354 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
356 if (IS_ERR(key)) { 355 if (IS_ERR(key)) {
357 ret = PTR_ERR(key); 356 ret = PTR_ERR(key);
358 goto error; 357 goto error;
@@ -378,7 +377,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
378 struct key *keyring; 377 struct key *keyring;
379 long ret; 378 long ret;
380 379
381 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 380 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
382 if (IS_ERR(keyring)) { 381 if (IS_ERR(keyring)) {
383 ret = PTR_ERR(keyring); 382 ret = PTR_ERR(keyring);
384 goto error; 383 goto error;
@@ -404,13 +403,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
404 struct key *keyring, *key; 403 struct key *keyring, *key;
405 long ret; 404 long ret;
406 405
407 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 406 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
408 if (IS_ERR(keyring)) { 407 if (IS_ERR(keyring)) {
409 ret = PTR_ERR(keyring); 408 ret = PTR_ERR(keyring);
410 goto error; 409 goto error;
411 } 410 }
412 411
413 key = lookup_user_key(id, 1, 0, KEY_LINK); 412 key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
414 if (IS_ERR(key)) { 413 if (IS_ERR(key)) {
415 ret = PTR_ERR(key); 414 ret = PTR_ERR(key);
416 goto error2; 415 goto error2;
@@ -438,13 +437,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
438 struct key *keyring, *key; 437 struct key *keyring, *key;
439 long ret; 438 long ret;
440 439
441 keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE); 440 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
442 if (IS_ERR(keyring)) { 441 if (IS_ERR(keyring)) {
443 ret = PTR_ERR(keyring); 442 ret = PTR_ERR(keyring);
444 goto error; 443 goto error;
445 } 444 }
446 445
447 key = lookup_user_key(id, 0, 0, 0); 446 key = lookup_user_key(NULL, id, 0, 0, 0);
448 if (IS_ERR(key)) { 447 if (IS_ERR(key)) {
449 ret = PTR_ERR(key); 448 ret = PTR_ERR(key);
450 goto error2; 449 goto error2;
@@ -475,16 +474,29 @@ long keyctl_describe_key(key_serial_t keyid,
475 char __user *buffer, 474 char __user *buffer,
476 size_t buflen) 475 size_t buflen)
477{ 476{
478 struct key *key; 477 struct key *key, *instkey;
479 char *tmpbuf; 478 char *tmpbuf;
480 long ret; 479 long ret;
481 480
482 key = lookup_user_key(keyid, 0, 1, KEY_VIEW); 481 key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
483 if (IS_ERR(key)) { 482 if (IS_ERR(key)) {
483 /* viewing a key under construction is permitted if we have the
484 * authorisation token handy */
485 if (PTR_ERR(key) == -EACCES) {
486 instkey = key_get_instantiation_authkey(keyid);
487 if (!IS_ERR(instkey)) {
488 key_put(instkey);
489 key = lookup_user_key(NULL, keyid, 0, 1, 0);
490 if (!IS_ERR(key))
491 goto okay;
492 }
493 }
494
484 ret = PTR_ERR(key); 495 ret = PTR_ERR(key);
485 goto error; 496 goto error;
486 } 497 }
487 498
499okay:
488 /* calculate how much description we're going to return */ 500 /* calculate how much description we're going to return */
489 ret = -ENOMEM; 501 ret = -ENOMEM;
490 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 502 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -568,7 +580,7 @@ long keyctl_keyring_search(key_serial_t ringid,
568 goto error2; 580 goto error2;
569 581
570 /* get the keyring at which to begin the search */ 582 /* get the keyring at which to begin the search */
571 keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH); 583 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
572 if (IS_ERR(keyring)) { 584 if (IS_ERR(keyring)) {
573 ret = PTR_ERR(keyring); 585 ret = PTR_ERR(keyring);
574 goto error2; 586 goto error2;
@@ -577,7 +589,7 @@ long keyctl_keyring_search(key_serial_t ringid,
577 /* get the destination keyring if specified */ 589 /* get the destination keyring if specified */
578 dest = NULL; 590 dest = NULL;
579 if (destringid) { 591 if (destringid) {
580 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 592 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
581 if (IS_ERR(dest)) { 593 if (IS_ERR(dest)) {
582 ret = PTR_ERR(dest); 594 ret = PTR_ERR(dest);
583 goto error3; 595 goto error3;
@@ -656,24 +668,23 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
656 long ret; 668 long ret;
657 669
658 /* find the key first */ 670 /* find the key first */
659 key = lookup_user_key(keyid, 0, 0, 0); 671 key = lookup_user_key(NULL, keyid, 0, 0, 0);
660 if (!IS_ERR(key)) { 672 if (!IS_ERR(key)) {
661 /* see if we can read it directly */ 673 /* see if we can read it directly */
662 if (key_permission(key, KEY_READ)) 674 if (key_permission(key, KEY_READ))
663 goto can_read_key; 675 goto can_read_key;
664 676
665 /* can't; see if it's searchable from this process's 677 /* we can't; see if it's searchable from this process's
666 * keyrings */ 678 * keyrings
667 ret = -ENOKEY; 679 * - we automatically take account of the fact that it may be
668 if (key_permission(key, KEY_SEARCH)) { 680 * dangling off an instantiation key
669 /* okay - we do have search permission on the key 681 */
670 * itself, but do we have the key? */ 682 skey = search_process_keyrings(key->type, key,
671 skey = search_process_keyrings_aux(key->type, key, 683 keyctl_read_key_same, current);
672 keyctl_read_key_same); 684 if (!IS_ERR(skey))
673 if (!IS_ERR(skey)) 685 goto can_read_key2;
674 goto can_read_key2; 686
675 } 687 ret = PTR_ERR(skey);
676
677 goto error2; 688 goto error2;
678 } 689 }
679 690
@@ -719,7 +730,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
719 if (uid == (uid_t) -1 && gid == (gid_t) -1) 730 if (uid == (uid_t) -1 && gid == (gid_t) -1)
720 goto error; 731 goto error;
721 732
722 key = lookup_user_key(id, 1, 1, 0); 733 key = lookup_user_key(NULL, id, 1, 1, 0);
723 if (IS_ERR(key)) { 734 if (IS_ERR(key)) {
724 ret = PTR_ERR(key); 735 ret = PTR_ERR(key);
725 goto error; 736 goto error;
@@ -776,7 +787,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
776 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 787 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
777 goto error; 788 goto error;
778 789
779 key = lookup_user_key(id, 1, 1, 0); 790 key = lookup_user_key(NULL, id, 1, 1, 0);
780 if (IS_ERR(key)) { 791 if (IS_ERR(key)) {
781 ret = PTR_ERR(key); 792 ret = PTR_ERR(key);
782 goto error; 793 goto error;
@@ -809,7 +820,8 @@ long keyctl_instantiate_key(key_serial_t id,
809 size_t plen, 820 size_t plen,
810 key_serial_t ringid) 821 key_serial_t ringid)
811{ 822{
812 struct key *key, *keyring; 823 struct request_key_auth *rka;
824 struct key *instkey, *keyring;
813 void *payload; 825 void *payload;
814 long ret; 826 long ret;
815 827
@@ -831,18 +843,21 @@ long keyctl_instantiate_key(key_serial_t id,
831 goto error2; 843 goto error2;
832 } 844 }
833 845
834 /* find the target key (which must be writable) */ 846 /* find the instantiation authorisation key */
835 key = lookup_user_key(id, 0, 1, KEY_WRITE); 847 instkey = key_get_instantiation_authkey(id);
836 if (IS_ERR(key)) { 848 if (IS_ERR(instkey)) {
837 ret = PTR_ERR(key); 849 ret = PTR_ERR(instkey);
838 goto error2; 850 goto error2;
839 } 851 }
840 852
841 /* find the destination keyring if present (which must also be 853 rka = instkey->payload.data;
842 * writable) */ 854
855 /* find the destination keyring amongst those belonging to the
856 * requesting task */
843 keyring = NULL; 857 keyring = NULL;
844 if (ringid) { 858 if (ringid) {
845 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 859 keyring = lookup_user_key(rka->context, ringid, 1, 0,
860 KEY_WRITE);
846 if (IS_ERR(keyring)) { 861 if (IS_ERR(keyring)) {
847 ret = PTR_ERR(keyring); 862 ret = PTR_ERR(keyring);
848 goto error3; 863 goto error3;
@@ -850,11 +865,12 @@ long keyctl_instantiate_key(key_serial_t id,
850 } 865 }
851 866
852 /* instantiate the key and link it into a keyring */ 867 /* instantiate the key and link it into a keyring */
853 ret = key_instantiate_and_link(key, payload, plen, keyring); 868 ret = key_instantiate_and_link(rka->target_key, payload, plen,
869 keyring, instkey);
854 870
855 key_put(keyring); 871 key_put(keyring);
856 error3: 872 error3:
857 key_put(key); 873 key_put(instkey);
858 error2: 874 error2:
859 kfree(payload); 875 kfree(payload);
860 error: 876 error:
@@ -869,21 +885,24 @@ long keyctl_instantiate_key(key_serial_t id,
869 */ 885 */
870long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 886long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
871{ 887{
872 struct key *key, *keyring; 888 struct request_key_auth *rka;
889 struct key *instkey, *keyring;
873 long ret; 890 long ret;
874 891
875 /* find the target key (which must be writable) */ 892 /* find the instantiation authorisation key */
876 key = lookup_user_key(id, 0, 1, KEY_WRITE); 893 instkey = key_get_instantiation_authkey(id);
877 if (IS_ERR(key)) { 894 if (IS_ERR(instkey)) {
878 ret = PTR_ERR(key); 895 ret = PTR_ERR(instkey);
879 goto error; 896 goto error;
880 } 897 }
881 898
899 rka = instkey->payload.data;
900
882 /* find the destination keyring if present (which must also be 901 /* find the destination keyring if present (which must also be
883 * writable) */ 902 * writable) */
884 keyring = NULL; 903 keyring = NULL;
885 if (ringid) { 904 if (ringid) {
886 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 905 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
887 if (IS_ERR(keyring)) { 906 if (IS_ERR(keyring)) {
888 ret = PTR_ERR(keyring); 907 ret = PTR_ERR(keyring);
889 goto error2; 908 goto error2;
@@ -891,11 +910,11 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
891 } 910 }
892 911
893 /* instantiate the key and link it into a keyring */ 912 /* instantiate the key and link it into a keyring */
894 ret = key_negate_and_link(key, timeout, keyring); 913 ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
895 914
896 key_put(keyring); 915 key_put(keyring);
897 error2: 916 error2:
898 key_put(key); 917 key_put(instkey);
899 error: 918 error:
900 return ret; 919 return ret;
901 920
@@ -903,6 +922,44 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
903 922
904/*****************************************************************************/ 923/*****************************************************************************/
905/* 924/*
925 * set the default keyring in which request_key() will cache keys
926 * - return the old setting
927 */
928long keyctl_set_reqkey_keyring(int reqkey_defl)
929{
930 int ret;
931
932 switch (reqkey_defl) {
933 case KEY_REQKEY_DEFL_THREAD_KEYRING:
934 ret = install_thread_keyring(current);
935 if (ret < 0)
936 return ret;
937 goto set;
938
939 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
940 ret = install_process_keyring(current);
941 if (ret < 0)
942 return ret;
943
944 case KEY_REQKEY_DEFL_DEFAULT:
945 case KEY_REQKEY_DEFL_SESSION_KEYRING:
946 case KEY_REQKEY_DEFL_USER_KEYRING:
947 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
948 set:
949 current->jit_keyring = reqkey_defl;
950
951 case KEY_REQKEY_DEFL_NO_CHANGE:
952 return current->jit_keyring;
953
954 case KEY_REQKEY_DEFL_GROUP_KEYRING:
955 default:
956 return -EINVAL;
957 }
958
959} /* end keyctl_set_reqkey_keyring() */
960
961/*****************************************************************************/
962/*
906 * the key control system call 963 * the key control system call
907 */ 964 */
908asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 965asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -971,6 +1028,9 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
971 (unsigned) arg3, 1028 (unsigned) arg3,
972 (key_serial_t) arg4); 1029 (key_serial_t) arg4);
973 1030
1031 case KEYCTL_SET_REQKEY_KEYRING:
1032 return keyctl_set_reqkey_keyring(arg2);
1033
974 default: 1034 default:
975 return -EOPNOTSUPP; 1035 return -EOPNOTSUPP;
976 } 1036 }