diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 118 |
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 | */ | ||
835 | static 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: | |||
924 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | 954 | long 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 | } |