diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 8833b447adef..7c72baa02f2e 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -866,6 +866,23 @@ static long get_instantiation_keyring(key_serial_t ringid, | |||
866 | return -ENOKEY; | 866 | return -ENOKEY; |
867 | } | 867 | } |
868 | 868 | ||
869 | /* | ||
870 | * change the request_key authorisation key on the current process | ||
871 | */ | ||
872 | static int keyctl_change_reqkey_auth(struct key *key) | ||
873 | { | ||
874 | struct cred *new; | ||
875 | |||
876 | new = prepare_creds(); | ||
877 | if (!new) | ||
878 | return -ENOMEM; | ||
879 | |||
880 | key_put(new->request_key_auth); | ||
881 | new->request_key_auth = key_get(key); | ||
882 | |||
883 | return commit_creds(new); | ||
884 | } | ||
885 | |||
869 | /*****************************************************************************/ | 886 | /*****************************************************************************/ |
870 | /* | 887 | /* |
871 | * instantiate the key with the specified payload, and, if one is given, link | 888 | * instantiate the key with the specified payload, and, if one is given, link |
@@ -876,12 +893,15 @@ long keyctl_instantiate_key(key_serial_t id, | |||
876 | size_t plen, | 893 | size_t plen, |
877 | key_serial_t ringid) | 894 | key_serial_t ringid) |
878 | { | 895 | { |
896 | const struct cred *cred = current_cred(); | ||
879 | struct request_key_auth *rka; | 897 | struct request_key_auth *rka; |
880 | struct key *instkey, *dest_keyring; | 898 | struct key *instkey, *dest_keyring; |
881 | void *payload; | 899 | void *payload; |
882 | long ret; | 900 | long ret; |
883 | bool vm = false; | 901 | bool vm = false; |
884 | 902 | ||
903 | kenter("%d,,%zu,%d", id, plen, ringid); | ||
904 | |||
885 | ret = -EINVAL; | 905 | ret = -EINVAL; |
886 | if (plen > 1024 * 1024 - 1) | 906 | if (plen > 1024 * 1024 - 1) |
887 | goto error; | 907 | goto error; |
@@ -889,7 +909,7 @@ long keyctl_instantiate_key(key_serial_t id, | |||
889 | /* the appropriate instantiation authorisation key must have been | 909 | /* the appropriate instantiation authorisation key must have been |
890 | * assumed before calling this */ | 910 | * assumed before calling this */ |
891 | ret = -EPERM; | 911 | ret = -EPERM; |
892 | instkey = current->cred->request_key_auth; | 912 | instkey = cred->request_key_auth; |
893 | if (!instkey) | 913 | if (!instkey) |
894 | goto error; | 914 | goto error; |
895 | 915 | ||
@@ -931,10 +951,8 @@ long keyctl_instantiate_key(key_serial_t id, | |||
931 | 951 | ||
932 | /* discard the assumed authority if it's just been disabled by | 952 | /* discard the assumed authority if it's just been disabled by |
933 | * instantiation of the key */ | 953 | * instantiation of the key */ |
934 | if (ret == 0) { | 954 | if (ret == 0) |
935 | key_put(current->cred->request_key_auth); | 955 | keyctl_change_reqkey_auth(NULL); |
936 | current->cred->request_key_auth = NULL; | ||
937 | } | ||
938 | 956 | ||
939 | error2: | 957 | error2: |
940 | if (!vm) | 958 | if (!vm) |
@@ -953,14 +971,17 @@ error: | |||
953 | */ | 971 | */ |
954 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | 972 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) |
955 | { | 973 | { |
974 | const struct cred *cred = current_cred(); | ||
956 | struct request_key_auth *rka; | 975 | struct request_key_auth *rka; |
957 | struct key *instkey, *dest_keyring; | 976 | struct key *instkey, *dest_keyring; |
958 | long ret; | 977 | long ret; |
959 | 978 | ||
979 | kenter("%d,%u,%d", id, timeout, ringid); | ||
980 | |||
960 | /* the appropriate instantiation authorisation key must have been | 981 | /* the appropriate instantiation authorisation key must have been |
961 | * assumed before calling this */ | 982 | * assumed before calling this */ |
962 | ret = -EPERM; | 983 | ret = -EPERM; |
963 | instkey = current->cred->request_key_auth; | 984 | instkey = cred->request_key_auth; |
964 | if (!instkey) | 985 | if (!instkey) |
965 | goto error; | 986 | goto error; |
966 | 987 | ||
@@ -982,10 +1003,8 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | |||
982 | 1003 | ||
983 | /* discard the assumed authority if it's just been disabled by | 1004 | /* discard the assumed authority if it's just been disabled by |
984 | * instantiation of the key */ | 1005 | * instantiation of the key */ |
985 | if (ret == 0) { | 1006 | if (ret == 0) |
986 | key_put(current->cred->request_key_auth); | 1007 | keyctl_change_reqkey_auth(NULL); |
987 | current->cred->request_key_auth = NULL; | ||
988 | } | ||
989 | 1008 | ||
990 | error: | 1009 | error: |
991 | return ret; | 1010 | return ret; |
@@ -999,36 +1018,56 @@ error: | |||
999 | */ | 1018 | */ |
1000 | long keyctl_set_reqkey_keyring(int reqkey_defl) | 1019 | long keyctl_set_reqkey_keyring(int reqkey_defl) |
1001 | { | 1020 | { |
1002 | struct cred *cred = current->cred; | 1021 | struct cred *new; |
1003 | int ret; | 1022 | int ret, old_setting; |
1023 | |||
1024 | old_setting = current_cred_xxx(jit_keyring); | ||
1025 | |||
1026 | if (reqkey_defl == KEY_REQKEY_DEFL_NO_CHANGE) | ||
1027 | return old_setting; | ||
1028 | |||
1029 | new = prepare_creds(); | ||
1030 | if (!new) | ||
1031 | return -ENOMEM; | ||
1004 | 1032 | ||
1005 | switch (reqkey_defl) { | 1033 | switch (reqkey_defl) { |
1006 | case KEY_REQKEY_DEFL_THREAD_KEYRING: | 1034 | case KEY_REQKEY_DEFL_THREAD_KEYRING: |
1007 | ret = install_thread_keyring(); | 1035 | ret = install_thread_keyring_to_cred(new); |
1008 | if (ret < 0) | 1036 | if (ret < 0) |
1009 | return ret; | 1037 | goto error; |
1010 | goto set; | 1038 | goto set; |
1011 | 1039 | ||
1012 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: | 1040 | case KEY_REQKEY_DEFL_PROCESS_KEYRING: |
1013 | ret = install_process_keyring(); | 1041 | ret = install_process_keyring_to_cred(new); |
1014 | if (ret < 0) | 1042 | if (ret < 0) { |
1015 | return ret; | 1043 | if (ret != -EEXIST) |
1044 | goto error; | ||
1045 | ret = 0; | ||
1046 | } | ||
1047 | goto set; | ||
1016 | 1048 | ||
1017 | case KEY_REQKEY_DEFL_DEFAULT: | 1049 | case KEY_REQKEY_DEFL_DEFAULT: |
1018 | case KEY_REQKEY_DEFL_SESSION_KEYRING: | 1050 | case KEY_REQKEY_DEFL_SESSION_KEYRING: |
1019 | case KEY_REQKEY_DEFL_USER_KEYRING: | 1051 | case KEY_REQKEY_DEFL_USER_KEYRING: |
1020 | case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: | 1052 | case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: |
1021 | set: | 1053 | case KEY_REQKEY_DEFL_REQUESTOR_KEYRING: |
1022 | cred->jit_keyring = reqkey_defl; | 1054 | goto set; |
1023 | 1055 | ||
1024 | case KEY_REQKEY_DEFL_NO_CHANGE: | 1056 | case KEY_REQKEY_DEFL_NO_CHANGE: |
1025 | return cred->jit_keyring; | ||
1026 | |||
1027 | case KEY_REQKEY_DEFL_GROUP_KEYRING: | 1057 | case KEY_REQKEY_DEFL_GROUP_KEYRING: |
1028 | default: | 1058 | default: |
1029 | return -EINVAL; | 1059 | ret = -EINVAL; |
1060 | goto error; | ||
1030 | } | 1061 | } |
1031 | 1062 | ||
1063 | set: | ||
1064 | new->jit_keyring = reqkey_defl; | ||
1065 | commit_creds(new); | ||
1066 | return old_setting; | ||
1067 | error: | ||
1068 | abort_creds(new); | ||
1069 | return -EINVAL; | ||
1070 | |||
1032 | } /* end keyctl_set_reqkey_keyring() */ | 1071 | } /* end keyctl_set_reqkey_keyring() */ |
1033 | 1072 | ||
1034 | /*****************************************************************************/ | 1073 | /*****************************************************************************/ |
@@ -1087,9 +1126,7 @@ long keyctl_assume_authority(key_serial_t id) | |||
1087 | 1126 | ||
1088 | /* we divest ourselves of authority if given an ID of 0 */ | 1127 | /* we divest ourselves of authority if given an ID of 0 */ |
1089 | if (id == 0) { | 1128 | if (id == 0) { |
1090 | key_put(current->cred->request_key_auth); | 1129 | ret = keyctl_change_reqkey_auth(NULL); |
1091 | current->cred->request_key_auth = NULL; | ||
1092 | ret = 0; | ||
1093 | goto error; | 1130 | goto error; |
1094 | } | 1131 | } |
1095 | 1132 | ||
@@ -1104,10 +1141,12 @@ long keyctl_assume_authority(key_serial_t id) | |||
1104 | goto error; | 1141 | goto error; |
1105 | } | 1142 | } |
1106 | 1143 | ||
1107 | key_put(current->cred->request_key_auth); | 1144 | ret = keyctl_change_reqkey_auth(authkey); |
1108 | current->cred->request_key_auth = authkey; | 1145 | if (ret < 0) |
1109 | ret = authkey->serial; | 1146 | goto error; |
1147 | key_put(authkey); | ||
1110 | 1148 | ||
1149 | ret = authkey->serial; | ||
1111 | error: | 1150 | error: |
1112 | return ret; | 1151 | return ret; |
1113 | 1152 | ||