aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:14 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:14 -0500
commit8bbf4976b59fc9fc2861e79cab7beb3f6d647640 (patch)
tree9bd621217cbdfcf94aca5b220de7363254d7fc23 /security/keys/keyctl.c
parente9e349b051d98799b743ebf248cc2d986fedf090 (diff)
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring arguments. Currently this specifies a keyring in the target process to link the key into, creating the keyring if it doesn't exist. This, however, can be a problem for copy-on-write credentials as it means that the instantiating process can alter the credentials of the requesting process. This patch alters the behaviour such that: (1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific keyring by ID (ringid >= 0), then that keyring will be used. (2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the special constants that refer to the requesting process's keyrings (KEY_SPEC_*_KEYRING, all <= 0), then: (a) If sys_request_key() was given a keyring to use (destringid) then the key will be attached to that keyring. (b) If sys_request_key() was given a NULL keyring, then the key being instantiated will be attached to the default keyring as set by keyctl_set_reqkey_keyring(). (3) No extra link will be made. Decision point (1) follows current behaviour, and allows those instantiators who've searched for a specifically named keyring in the requestor's keyring so as to partition the keys by type to still have their named keyrings. Decision point (2) allows the requestor to make sure that the key or keys that get produced by request_key() go where they want, whilst allowing the instantiator to request that the key is retained. This is mainly useful for situations where the instantiator makes a secondary request, the key for which should be retained by the initial requestor: +-----------+ +--------------+ +--------------+ | | | | | | | Requestor |------->| Instantiator |------->| Instantiator | | | | | | | +-----------+ +--------------+ +--------------+ request_key() request_key() This might be useful, for example, in Kerberos, where the requestor requests a ticket, and then the ticket instantiator requests the TGT, which someone else then has to go and fetch. The TGT, however, should be retained in the keyrings of the requestor, not the first instantiator. To make this explict an extra special keyring constant is also added. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: James Morris <jmorris@namei.org> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c118
1 files changed, 71 insertions, 47 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3f09e5b2a784..fcce331eca72 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -103,7 +103,7 @@ asmlinkage long sys_add_key(const char __user *_type,
103 } 103 }
104 104
105 /* find the target keyring (which must be writable) */ 105 /* find the target keyring (which must be writable) */
106 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 106 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE);
107 if (IS_ERR(keyring_ref)) { 107 if (IS_ERR(keyring_ref)) {
108 ret = PTR_ERR(keyring_ref); 108 ret = PTR_ERR(keyring_ref);
109 goto error3; 109 goto error3;
@@ -185,7 +185,7 @@ asmlinkage long sys_request_key(const char __user *_type,
185 /* get the destination keyring if specified */ 185 /* get the destination keyring if specified */
186 dest_ref = NULL; 186 dest_ref = NULL;
187 if (destringid) { 187 if (destringid) {
188 dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 188 dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE);
189 if (IS_ERR(dest_ref)) { 189 if (IS_ERR(dest_ref)) {
190 ret = PTR_ERR(dest_ref); 190 ret = PTR_ERR(dest_ref);
191 goto error3; 191 goto error3;
@@ -235,7 +235,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
235 key_ref_t key_ref; 235 key_ref_t key_ref;
236 long ret; 236 long ret;
237 237
238 key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); 238 key_ref = lookup_user_key(id, create, 0, KEY_SEARCH);
239 if (IS_ERR(key_ref)) { 239 if (IS_ERR(key_ref)) {
240 ret = PTR_ERR(key_ref); 240 ret = PTR_ERR(key_ref);
241 goto error; 241 goto error;
@@ -308,7 +308,7 @@ long keyctl_update_key(key_serial_t id,
308 } 308 }
309 309
310 /* find the target key (which must be writable) */ 310 /* find the target key (which must be writable) */
311 key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 311 key_ref = lookup_user_key(id, 0, 0, KEY_WRITE);
312 if (IS_ERR(key_ref)) { 312 if (IS_ERR(key_ref)) {
313 ret = PTR_ERR(key_ref); 313 ret = PTR_ERR(key_ref);
314 goto error2; 314 goto error2;
@@ -336,7 +336,7 @@ long keyctl_revoke_key(key_serial_t id)
336 key_ref_t key_ref; 336 key_ref_t key_ref;
337 long ret; 337 long ret;
338 338
339 key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 339 key_ref = lookup_user_key(id, 0, 0, KEY_WRITE);
340 if (IS_ERR(key_ref)) { 340 if (IS_ERR(key_ref)) {
341 ret = PTR_ERR(key_ref); 341 ret = PTR_ERR(key_ref);
342 goto error; 342 goto error;
@@ -362,7 +362,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
362 key_ref_t keyring_ref; 362 key_ref_t keyring_ref;
363 long ret; 363 long ret;
364 364
365 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 365 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE);
366 if (IS_ERR(keyring_ref)) { 366 if (IS_ERR(keyring_ref)) {
367 ret = PTR_ERR(keyring_ref); 367 ret = PTR_ERR(keyring_ref);
368 goto error; 368 goto error;
@@ -388,13 +388,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
388 key_ref_t keyring_ref, key_ref; 388 key_ref_t keyring_ref, key_ref;
389 long ret; 389 long ret;
390 390
391 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 391 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE);
392 if (IS_ERR(keyring_ref)) { 392 if (IS_ERR(keyring_ref)) {
393 ret = PTR_ERR(keyring_ref); 393 ret = PTR_ERR(keyring_ref);
394 goto error; 394 goto error;
395 } 395 }
396 396
397 key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK); 397 key_ref = lookup_user_key(id, 1, 0, KEY_LINK);
398 if (IS_ERR(key_ref)) { 398 if (IS_ERR(key_ref)) {
399 ret = PTR_ERR(key_ref); 399 ret = PTR_ERR(key_ref);
400 goto error2; 400 goto error2;
@@ -422,13 +422,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
422 key_ref_t keyring_ref, key_ref; 422 key_ref_t keyring_ref, key_ref;
423 long ret; 423 long ret;
424 424
425 keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); 425 keyring_ref = lookup_user_key(ringid, 0, 0, KEY_WRITE);
426 if (IS_ERR(keyring_ref)) { 426 if (IS_ERR(keyring_ref)) {
427 ret = PTR_ERR(keyring_ref); 427 ret = PTR_ERR(keyring_ref);
428 goto error; 428 goto error;
429 } 429 }
430 430
431 key_ref = lookup_user_key(NULL, id, 0, 0, 0); 431 key_ref = lookup_user_key(id, 0, 0, 0);
432 if (IS_ERR(key_ref)) { 432 if (IS_ERR(key_ref)) {
433 ret = PTR_ERR(key_ref); 433 ret = PTR_ERR(key_ref);
434 goto error2; 434 goto error2;
@@ -464,7 +464,7 @@ long keyctl_describe_key(key_serial_t keyid,
464 char *tmpbuf; 464 char *tmpbuf;
465 long ret; 465 long ret;
466 466
467 key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); 467 key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW);
468 if (IS_ERR(key_ref)) { 468 if (IS_ERR(key_ref)) {
469 /* viewing a key under construction is permitted if we have the 469 /* viewing a key under construction is permitted if we have the
470 * authorisation token handy */ 470 * authorisation token handy */
@@ -472,7 +472,7 @@ long keyctl_describe_key(key_serial_t keyid,
472 instkey = key_get_instantiation_authkey(keyid); 472 instkey = key_get_instantiation_authkey(keyid);
473 if (!IS_ERR(instkey)) { 473 if (!IS_ERR(instkey)) {
474 key_put(instkey); 474 key_put(instkey);
475 key_ref = lookup_user_key(NULL, keyid, 475 key_ref = lookup_user_key(keyid,
476 0, 1, 0); 476 0, 1, 0);
477 if (!IS_ERR(key_ref)) 477 if (!IS_ERR(key_ref))
478 goto okay; 478 goto okay;
@@ -557,7 +557,7 @@ long keyctl_keyring_search(key_serial_t ringid,
557 } 557 }
558 558
559 /* get the keyring at which to begin the search */ 559 /* get the keyring at which to begin the search */
560 keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); 560 keyring_ref = lookup_user_key(ringid, 0, 0, KEY_SEARCH);
561 if (IS_ERR(keyring_ref)) { 561 if (IS_ERR(keyring_ref)) {
562 ret = PTR_ERR(keyring_ref); 562 ret = PTR_ERR(keyring_ref);
563 goto error2; 563 goto error2;
@@ -566,7 +566,7 @@ long keyctl_keyring_search(key_serial_t ringid,
566 /* get the destination keyring if specified */ 566 /* get the destination keyring if specified */
567 dest_ref = NULL; 567 dest_ref = NULL;
568 if (destringid) { 568 if (destringid) {
569 dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 569 dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE);
570 if (IS_ERR(dest_ref)) { 570 if (IS_ERR(dest_ref)) {
571 ret = PTR_ERR(dest_ref); 571 ret = PTR_ERR(dest_ref);
572 goto error3; 572 goto error3;
@@ -636,7 +636,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
636 long ret; 636 long ret;
637 637
638 /* find the key first */ 638 /* find the key first */
639 key_ref = lookup_user_key(NULL, keyid, 0, 0, 0); 639 key_ref = lookup_user_key(keyid, 0, 0, 0);
640 if (IS_ERR(key_ref)) { 640 if (IS_ERR(key_ref)) {
641 ret = -ENOKEY; 641 ret = -ENOKEY;
642 goto error; 642 goto error;
@@ -699,7 +699,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
699 if (uid == (uid_t) -1 && gid == (gid_t) -1) 699 if (uid == (uid_t) -1 && gid == (gid_t) -1)
700 goto error; 700 goto error;
701 701
702 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); 702 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR);
703 if (IS_ERR(key_ref)) { 703 if (IS_ERR(key_ref)) {
704 ret = PTR_ERR(key_ref); 704 ret = PTR_ERR(key_ref);
705 goto error; 705 goto error;
@@ -804,7 +804,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
804 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 804 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
805 goto error; 805 goto error;
806 806
807 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); 807 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR);
808 if (IS_ERR(key_ref)) { 808 if (IS_ERR(key_ref)) {
809 ret = PTR_ERR(key_ref); 809 ret = PTR_ERR(key_ref);
810 goto error; 810 goto error;
@@ -829,6 +829,43 @@ error:
829 829
830} /* end keyctl_setperm_key() */ 830} /* end keyctl_setperm_key() */
831 831
832/*
833 * get the destination keyring for instantiation
834 */
835static long get_instantiation_keyring(key_serial_t ringid,
836 struct request_key_auth *rka,
837 struct key **_dest_keyring)
838{
839 key_ref_t dkref;
840
841 /* just return a NULL pointer if we weren't asked to make a link */
842 if (ringid == 0) {
843 *_dest_keyring = NULL;
844 return 0;
845 }
846
847 /* if a specific keyring is nominated by ID, then use that */
848 if (ringid > 0) {
849 dkref = lookup_user_key(ringid, 1, 0, KEY_WRITE);
850 if (IS_ERR(dkref))
851 return PTR_ERR(dkref);
852 *_dest_keyring = key_ref_to_ptr(dkref);
853 return 0;
854 }
855
856 if (ringid == KEY_SPEC_REQKEY_AUTH_KEY)
857 return -EINVAL;
858
859 /* otherwise specify the destination keyring recorded in the
860 * authorisation key (any KEY_SPEC_*_KEYRING) */
861 if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) {
862 *_dest_keyring = rka->dest_keyring;
863 return 0;
864 }
865
866 return -ENOKEY;
867}
868
832/*****************************************************************************/ 869/*****************************************************************************/
833/* 870/*
834 * instantiate the key with the specified payload, and, if one is given, link 871 * instantiate the key with the specified payload, and, if one is given, link
@@ -840,8 +877,7 @@ long keyctl_instantiate_key(key_serial_t id,
840 key_serial_t ringid) 877 key_serial_t ringid)
841{ 878{
842 struct request_key_auth *rka; 879 struct request_key_auth *rka;
843 struct key *instkey; 880 struct key *instkey, *dest_keyring;
844 key_ref_t keyring_ref;
845 void *payload; 881 void *payload;
846 long ret; 882 long ret;
847 bool vm = false; 883 bool vm = false;
@@ -883,21 +919,15 @@ long keyctl_instantiate_key(key_serial_t id,
883 919
884 /* find the destination keyring amongst those belonging to the 920 /* find the destination keyring amongst those belonging to the
885 * requesting task */ 921 * requesting task */
886 keyring_ref = NULL; 922 ret = get_instantiation_keyring(ringid, rka, &dest_keyring);
887 if (ringid) { 923 if (ret < 0)
888 keyring_ref = lookup_user_key(rka->context, ringid, 1, 0, 924 goto error2;
889 KEY_WRITE);
890 if (IS_ERR(keyring_ref)) {
891 ret = PTR_ERR(keyring_ref);
892 goto error2;
893 }
894 }
895 925
896 /* instantiate the key and link it into a keyring */ 926 /* instantiate the key and link it into a keyring */
897 ret = key_instantiate_and_link(rka->target_key, payload, plen, 927 ret = key_instantiate_and_link(rka->target_key, payload, plen,
898 key_ref_to_ptr(keyring_ref), instkey); 928 dest_keyring, instkey);
899 929
900 key_ref_put(keyring_ref); 930 key_put(dest_keyring);
901 931
902 /* discard the assumed authority if it's just been disabled by 932 /* discard the assumed authority if it's just been disabled by
903 * instantiation of the key */ 933 * instantiation of the key */
@@ -924,8 +954,7 @@ error:
924long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 954long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
925{ 955{
926 struct request_key_auth *rka; 956 struct request_key_auth *rka;
927 struct key *instkey; 957 struct key *instkey, *dest_keyring;
928 key_ref_t keyring_ref;
929 long ret; 958 long ret;
930 959
931 /* the appropriate instantiation authorisation key must have been 960 /* the appropriate instantiation authorisation key must have been
@@ -941,20 +970,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
941 970
942 /* find the destination keyring if present (which must also be 971 /* find the destination keyring if present (which must also be
943 * writable) */ 972 * writable) */
944 keyring_ref = NULL; 973 ret = get_instantiation_keyring(ringid, rka, &dest_keyring);
945 if (ringid) { 974 if (ret < 0)
946 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 975 goto error;
947 if (IS_ERR(keyring_ref)) {
948 ret = PTR_ERR(keyring_ref);
949 goto error;
950 }
951 }
952 976
953 /* instantiate the key and link it into a keyring */ 977 /* instantiate the key and link it into a keyring */
954 ret = key_negate_and_link(rka->target_key, timeout, 978 ret = key_negate_and_link(rka->target_key, timeout,
955 key_ref_to_ptr(keyring_ref), instkey); 979 dest_keyring, instkey);
956 980
957 key_ref_put(keyring_ref); 981 key_put(dest_keyring);
958 982
959 /* discard the assumed authority if it's just been disabled by 983 /* discard the assumed authority if it's just been disabled by
960 * instantiation of the key */ 984 * instantiation of the key */
@@ -979,13 +1003,13 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
979 1003
980 switch (reqkey_defl) { 1004 switch (reqkey_defl) {
981 case KEY_REQKEY_DEFL_THREAD_KEYRING: 1005 case KEY_REQKEY_DEFL_THREAD_KEYRING:
982 ret = install_thread_keyring(current); 1006 ret = install_thread_keyring();
983 if (ret < 0) 1007 if (ret < 0)
984 return ret; 1008 return ret;
985 goto set; 1009 goto set;
986 1010
987 case KEY_REQKEY_DEFL_PROCESS_KEYRING: 1011 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
988 ret = install_process_keyring(current); 1012 ret = install_process_keyring();
989 if (ret < 0) 1013 if (ret < 0)
990 return ret; 1014 return ret;
991 1015
@@ -1018,7 +1042,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
1018 time_t expiry; 1042 time_t expiry;
1019 long ret; 1043 long ret;
1020 1044
1021 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); 1045 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR);
1022 if (IS_ERR(key_ref)) { 1046 if (IS_ERR(key_ref)) {
1023 ret = PTR_ERR(key_ref); 1047 ret = PTR_ERR(key_ref);
1024 goto error; 1048 goto error;
@@ -1105,7 +1129,7 @@ long keyctl_get_security(key_serial_t keyid,
1105 char *context; 1129 char *context;
1106 long ret; 1130 long ret;
1107 1131
1108 key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); 1132 key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW);
1109 if (IS_ERR(key_ref)) { 1133 if (IS_ERR(key_ref)) {
1110 if (PTR_ERR(key_ref) != -EACCES) 1134 if (PTR_ERR(key_ref) != -EACCES)
1111 return PTR_ERR(key_ref); 1135 return PTR_ERR(key_ref);
@@ -1117,7 +1141,7 @@ long keyctl_get_security(key_serial_t keyid,
1117 return PTR_ERR(key_ref); 1141 return PTR_ERR(key_ref);
1118 key_put(instkey); 1142 key_put(instkey);
1119 1143
1120 key_ref = lookup_user_key(NULL, keyid, 0, 1, 0); 1144 key_ref = lookup_user_key(keyid, 0, 1, 0);
1121 if (IS_ERR(key_ref)) 1145 if (IS_ERR(key_ref))
1122 return PTR_ERR(key_ref); 1146 return PTR_ERR(key_ref);
1123 } 1147 }