aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/internal.h17
-rw-r--r--security/keys/key.c25
-rw-r--r--security/keys/keyctl.c95
-rw-r--r--security/keys/keyring.c14
-rw-r--r--security/keys/permission.c24
-rw-r--r--security/keys/proc.c8
-rw-r--r--security/keys/process_keys.c333
-rw-r--r--security/keys/request_key.c29
-rw-r--r--security/keys/request_key_auth.c41
9 files changed, 317 insertions, 269 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index d1586c629788..81932abefe7b 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -12,6 +12,7 @@
12#ifndef _INTERNAL_H 12#ifndef _INTERNAL_H
13#define _INTERNAL_H 13#define _INTERNAL_H
14 14
15#include <linux/sched.h>
15#include <linux/key-type.h> 16#include <linux/key-type.h>
16 17
17static inline __attribute__((format(printf, 1, 2))) 18static inline __attribute__((format(printf, 1, 2)))
@@ -25,7 +26,7 @@ void no_printk(const char *fmt, ...)
25#define kleave(FMT, ...) \ 26#define kleave(FMT, ...) \
26 printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) 27 printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
27#define kdebug(FMT, ...) \ 28#define kdebug(FMT, ...) \
28 printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__) 29 printk(KERN_DEBUG " "FMT"\n", ##__VA_ARGS__)
29#else 30#else
30#define kenter(FMT, ...) \ 31#define kenter(FMT, ...) \
31 no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) 32 no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__)
@@ -97,7 +98,7 @@ extern struct key *keyring_search_instkey(struct key *keyring,
97typedef int (*key_match_func_t)(const struct key *, const void *); 98typedef int (*key_match_func_t)(const struct key *, const void *);
98 99
99extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 100extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
100 struct task_struct *tsk, 101 const struct cred *cred,
101 struct key_type *type, 102 struct key_type *type,
102 const void *description, 103 const void *description,
103 key_match_func_t match); 104 key_match_func_t match);
@@ -105,13 +106,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
105extern key_ref_t search_process_keyrings(struct key_type *type, 106extern key_ref_t search_process_keyrings(struct key_type *type,
106 const void *description, 107 const void *description,
107 key_match_func_t match, 108 key_match_func_t match,
108 struct task_struct *tsk); 109 const struct cred *cred);
109 110
110extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); 111extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
111 112
112extern int install_user_keyrings(void); 113extern int install_user_keyrings(void);
113extern int install_thread_keyring(void); 114extern int install_thread_keyring_to_cred(struct cred *);
114extern int install_process_keyring(void); 115extern int install_process_keyring_to_cred(struct cred *);
115 116
116extern struct key *request_key_and_link(struct key_type *type, 117extern struct key *request_key_and_link(struct key_type *type,
117 const char *description, 118 const char *description,
@@ -130,12 +131,12 @@ extern long join_session_keyring(const char *name);
130 * check to see whether permission is granted to use a key in the desired way 131 * check to see whether permission is granted to use a key in the desired way
131 */ 132 */
132extern int key_task_permission(const key_ref_t key_ref, 133extern int key_task_permission(const key_ref_t key_ref,
133 struct task_struct *context, 134 const struct cred *cred,
134 key_perm_t perm); 135 key_perm_t perm);
135 136
136static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) 137static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
137{ 138{
138 return key_task_permission(key_ref, current, perm); 139 return key_task_permission(key_ref, current_cred(), perm);
139} 140}
140 141
141/* required permissions */ 142/* required permissions */
@@ -153,7 +154,7 @@ static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
153struct request_key_auth { 154struct request_key_auth {
154 struct key *target_key; 155 struct key *target_key;
155 struct key *dest_keyring; 156 struct key *dest_keyring;
156 struct task_struct *context; 157 const struct cred *cred;
157 void *callout_info; 158 void *callout_info;
158 size_t callout_len; 159 size_t callout_len;
159 pid_t pid; 160 pid_t pid;
diff --git a/security/keys/key.c b/security/keys/key.c
index a6ca39ed3b0e..f76c8a546fd3 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -218,7 +218,7 @@ serial_exists:
218 * instantiate the key or discard it before returning 218 * instantiate the key or discard it before returning
219 */ 219 */
220struct key *key_alloc(struct key_type *type, const char *desc, 220struct key *key_alloc(struct key_type *type, const char *desc,
221 uid_t uid, gid_t gid, struct task_struct *ctx, 221 uid_t uid, gid_t gid, const struct cred *cred,
222 key_perm_t perm, unsigned long flags) 222 key_perm_t perm, unsigned long flags)
223{ 223{
224 struct key_user *user = NULL; 224 struct key_user *user = NULL;
@@ -294,7 +294,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
294#endif 294#endif
295 295
296 /* let the security module know about the key */ 296 /* let the security module know about the key */
297 ret = security_key_alloc(key, ctx, flags); 297 ret = security_key_alloc(key, cred, flags);
298 if (ret < 0) 298 if (ret < 0)
299 goto security_error; 299 goto security_error;
300 300
@@ -391,7 +391,7 @@ static int __key_instantiate_and_link(struct key *key,
391 const void *data, 391 const void *data,
392 size_t datalen, 392 size_t datalen,
393 struct key *keyring, 393 struct key *keyring,
394 struct key *instkey) 394 struct key *authkey)
395{ 395{
396 int ret, awaken; 396 int ret, awaken;
397 397
@@ -421,8 +421,8 @@ static int __key_instantiate_and_link(struct key *key,
421 ret = __key_link(keyring, key); 421 ret = __key_link(keyring, key);
422 422
423 /* disable the authorisation key */ 423 /* disable the authorisation key */
424 if (instkey) 424 if (authkey)
425 key_revoke(instkey); 425 key_revoke(authkey);
426 } 426 }
427 } 427 }
428 428
@@ -444,14 +444,14 @@ int key_instantiate_and_link(struct key *key,
444 const void *data, 444 const void *data,
445 size_t datalen, 445 size_t datalen,
446 struct key *keyring, 446 struct key *keyring,
447 struct key *instkey) 447 struct key *authkey)
448{ 448{
449 int ret; 449 int ret;
450 450
451 if (keyring) 451 if (keyring)
452 down_write(&keyring->sem); 452 down_write(&keyring->sem);
453 453
454 ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey); 454 ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey);
455 455
456 if (keyring) 456 if (keyring)
457 up_write(&keyring->sem); 457 up_write(&keyring->sem);
@@ -469,7 +469,7 @@ EXPORT_SYMBOL(key_instantiate_and_link);
469int key_negate_and_link(struct key *key, 469int key_negate_and_link(struct key *key,
470 unsigned timeout, 470 unsigned timeout,
471 struct key *keyring, 471 struct key *keyring,
472 struct key *instkey) 472 struct key *authkey)
473{ 473{
474 struct timespec now; 474 struct timespec now;
475 int ret, awaken; 475 int ret, awaken;
@@ -504,8 +504,8 @@ int key_negate_and_link(struct key *key,
504 ret = __key_link(keyring, key); 504 ret = __key_link(keyring, key);
505 505
506 /* disable the authorisation key */ 506 /* disable the authorisation key */
507 if (instkey) 507 if (authkey)
508 key_revoke(instkey); 508 key_revoke(authkey);
509 } 509 }
510 510
511 mutex_unlock(&key_construction_mutex); 511 mutex_unlock(&key_construction_mutex);
@@ -743,6 +743,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
743 key_perm_t perm, 743 key_perm_t perm,
744 unsigned long flags) 744 unsigned long flags)
745{ 745{
746 const struct cred *cred = current_cred();
746 struct key_type *ktype; 747 struct key_type *ktype;
747 struct key *keyring, *key = NULL; 748 struct key *keyring, *key = NULL;
748 key_ref_t key_ref; 749 key_ref_t key_ref;
@@ -802,8 +803,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
802 } 803 }
803 804
804 /* allocate a new key */ 805 /* allocate a new key */
805 key = key_alloc(ktype, description, current_fsuid(), current_fsgid(), 806 key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
806 current, perm, flags); 807 perm, flags);
807 if (IS_ERR(key)) { 808 if (IS_ERR(key)) {
808 key_ref = ERR_CAST(key); 809 key_ref = ERR_CAST(key);
809 goto error_3; 810 goto error_3;
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 */
872static 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
939error2: 957error2:
940 if (!vm) 958 if (!vm)
@@ -953,14 +971,17 @@ error:
953 */ 971 */
954long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 972long 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
990error: 1009error:
991 return ret; 1010 return ret;
@@ -999,36 +1018,56 @@ error:
999 */ 1018 */
1000long keyctl_set_reqkey_keyring(int reqkey_defl) 1019long 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
1063set:
1064 new->jit_keyring = reqkey_defl;
1065 commit_creds(new);
1066 return old_setting;
1067error:
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;
1111error: 1150error:
1112 return ret; 1151 return ret;
1113 1152
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index fdf75f901991..ed851574d073 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -245,14 +245,14 @@ static long keyring_read(const struct key *keyring,
245 * allocate a keyring and link into the destination keyring 245 * allocate a keyring and link into the destination keyring
246 */ 246 */
247struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 247struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
248 struct task_struct *ctx, unsigned long flags, 248 const struct cred *cred, unsigned long flags,
249 struct key *dest) 249 struct key *dest)
250{ 250{
251 struct key *keyring; 251 struct key *keyring;
252 int ret; 252 int ret;
253 253
254 keyring = key_alloc(&key_type_keyring, description, 254 keyring = key_alloc(&key_type_keyring, description,
255 uid, gid, ctx, 255 uid, gid, cred,
256 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 256 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
257 flags); 257 flags);
258 258
@@ -281,7 +281,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
281 * - we propagate the possession attribute from the keyring ref to the key ref 281 * - we propagate the possession attribute from the keyring ref to the key ref
282 */ 282 */
283key_ref_t keyring_search_aux(key_ref_t keyring_ref, 283key_ref_t keyring_search_aux(key_ref_t keyring_ref,
284 struct task_struct *context, 284 const struct cred *cred,
285 struct key_type *type, 285 struct key_type *type,
286 const void *description, 286 const void *description,
287 key_match_func_t match) 287 key_match_func_t match)
@@ -304,7 +304,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
304 key_check(keyring); 304 key_check(keyring);
305 305
306 /* top keyring must have search permission to begin the search */ 306 /* top keyring must have search permission to begin the search */
307 err = key_task_permission(keyring_ref, context, KEY_SEARCH); 307 err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
308 if (err < 0) { 308 if (err < 0) {
309 key_ref = ERR_PTR(err); 309 key_ref = ERR_PTR(err);
310 goto error; 310 goto error;
@@ -377,7 +377,7 @@ descend:
377 377
378 /* key must have search permissions */ 378 /* key must have search permissions */
379 if (key_task_permission(make_key_ref(key, possessed), 379 if (key_task_permission(make_key_ref(key, possessed),
380 context, KEY_SEARCH) < 0) 380 cred, KEY_SEARCH) < 0)
381 continue; 381 continue;
382 382
383 /* we set a different error code if we pass a negative key */ 383 /* we set a different error code if we pass a negative key */
@@ -404,7 +404,7 @@ ascend:
404 continue; 404 continue;
405 405
406 if (key_task_permission(make_key_ref(key, possessed), 406 if (key_task_permission(make_key_ref(key, possessed),
407 context, KEY_SEARCH) < 0) 407 cred, KEY_SEARCH) < 0)
408 continue; 408 continue;
409 409
410 /* stack the current position */ 410 /* stack the current position */
@@ -459,7 +459,7 @@ key_ref_t keyring_search(key_ref_t keyring,
459 if (!type->match) 459 if (!type->match)
460 return ERR_PTR(-ENOKEY); 460 return ERR_PTR(-ENOKEY);
461 461
462 return keyring_search_aux(keyring, current, 462 return keyring_search_aux(keyring, current->cred,
463 type, description, type->match); 463 type, description, type->match);
464 464
465} /* end keyring_search() */ 465} /* end keyring_search() */
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 13c36164f284..5d9fc7b93f2e 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -14,24 +14,27 @@
14#include "internal.h" 14#include "internal.h"
15 15
16/*****************************************************************************/ 16/*****************************************************************************/
17/* 17/**
18 * check to see whether permission is granted to use a key in the desired way, 18 * key_task_permission - Check a key can be used
19 * but permit the security modules to override 19 * @key_ref: The key to check
20 * @cred: The credentials to use
21 * @perm: The permissions to check for
22 *
23 * Check to see whether permission is granted to use a key in the desired way,
24 * but permit the security modules to override.
25 *
26 * The caller must hold either a ref on cred or must hold the RCU readlock or a
27 * spinlock.
20 */ 28 */
21int key_task_permission(const key_ref_t key_ref, 29int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
22 struct task_struct *context,
23 key_perm_t perm) 30 key_perm_t perm)
24{ 31{
25 const struct cred *cred;
26 struct key *key; 32 struct key *key;
27 key_perm_t kperm; 33 key_perm_t kperm;
28 int ret; 34 int ret;
29 35
30 key = key_ref_to_ptr(key_ref); 36 key = key_ref_to_ptr(key_ref);
31 37
32 rcu_read_lock();
33 cred = __task_cred(context);
34
35 /* use the second 8-bits of permissions for keys the caller owns */ 38 /* use the second 8-bits of permissions for keys the caller owns */
36 if (key->uid == cred->fsuid) { 39 if (key->uid == cred->fsuid) {
37 kperm = key->perm >> 16; 40 kperm = key->perm >> 16;
@@ -57,7 +60,6 @@ int key_task_permission(const key_ref_t key_ref,
57 kperm = key->perm; 60 kperm = key->perm;
58 61
59use_these_perms: 62use_these_perms:
60 rcu_read_lock();
61 63
62 /* use the top 8-bits of permissions for keys the caller possesses 64 /* use the top 8-bits of permissions for keys the caller possesses
63 * - possessor permissions are additive with other permissions 65 * - possessor permissions are additive with other permissions
@@ -71,7 +73,7 @@ use_these_perms:
71 return -EACCES; 73 return -EACCES;
72 74
73 /* let LSM be the final arbiter */ 75 /* let LSM be the final arbiter */
74 return security_key_permission(key_ref, context, perm); 76 return security_key_permission(key_ref, cred, perm);
75 77
76} /* end key_task_permission() */ 78} /* end key_task_permission() */
77 79
diff --git a/security/keys/proc.c b/security/keys/proc.c
index f619170da760..7f508def50e3 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -136,8 +136,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
136 int rc; 136 int rc;
137 137
138 /* check whether the current task is allowed to view the key (assuming 138 /* check whether the current task is allowed to view the key (assuming
139 * non-possession) */ 139 * non-possession)
140 rc = key_task_permission(make_key_ref(key, 0), current, KEY_VIEW); 140 * - the caller holds a spinlock, and thus the RCU read lock, making our
141 * access to __current_cred() safe
142 */
143 rc = key_task_permission(make_key_ref(key, 0), current_cred(),
144 KEY_VIEW);
141 if (rc < 0) 145 if (rc < 0)
142 return 0; 146 return 0;
143 147
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 70ee93406f30..df329f684a65 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -42,11 +42,15 @@ struct key_user root_key_user = {
42 */ 42 */
43int install_user_keyrings(void) 43int install_user_keyrings(void)
44{ 44{
45 struct user_struct *user = current->cred->user; 45 struct user_struct *user;
46 const struct cred *cred;
46 struct key *uid_keyring, *session_keyring; 47 struct key *uid_keyring, *session_keyring;
47 char buf[20]; 48 char buf[20];
48 int ret; 49 int ret;
49 50
51 cred = current_cred();
52 user = cred->user;
53
50 kenter("%p{%u}", user, user->uid); 54 kenter("%p{%u}", user, user->uid);
51 55
52 if (user->uid_keyring) { 56 if (user->uid_keyring) {
@@ -67,7 +71,7 @@ int install_user_keyrings(void)
67 uid_keyring = find_keyring_by_name(buf, true); 71 uid_keyring = find_keyring_by_name(buf, true);
68 if (IS_ERR(uid_keyring)) { 72 if (IS_ERR(uid_keyring)) {
69 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 73 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
70 current, KEY_ALLOC_IN_QUOTA, 74 cred, KEY_ALLOC_IN_QUOTA,
71 NULL); 75 NULL);
72 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
73 ret = PTR_ERR(uid_keyring); 77 ret = PTR_ERR(uid_keyring);
@@ -83,8 +87,7 @@ int install_user_keyrings(void)
83 if (IS_ERR(session_keyring)) { 87 if (IS_ERR(session_keyring)) {
84 session_keyring = 88 session_keyring =
85 keyring_alloc(buf, user->uid, (gid_t) -1, 89 keyring_alloc(buf, user->uid, (gid_t) -1,
86 current, KEY_ALLOC_IN_QUOTA, 90 cred, KEY_ALLOC_IN_QUOTA, NULL);
87 NULL);
88 if (IS_ERR(session_keyring)) { 91 if (IS_ERR(session_keyring)) {
89 ret = PTR_ERR(session_keyring); 92 ret = PTR_ERR(session_keyring);
90 goto error_release; 93 goto error_release;
@@ -116,142 +119,128 @@ error:
116 return ret; 119 return ret;
117} 120}
118 121
119/*****************************************************************************/
120/* 122/*
121 * deal with the UID changing 123 * install a fresh thread keyring directly to new credentials
122 */ 124 */
123void switch_uid_keyring(struct user_struct *new_user) 125int install_thread_keyring_to_cred(struct cred *new)
124{ 126{
125#if 0 /* do nothing for now */ 127 struct key *keyring;
126 struct key *old;
127
128 /* switch to the new user's session keyring if we were running under
129 * root's default session keyring */
130 if (new_user->uid != 0 &&
131 current->session_keyring == &root_session_keyring
132 ) {
133 atomic_inc(&new_user->session_keyring->usage);
134
135 task_lock(current);
136 old = current->session_keyring;
137 current->session_keyring = new_user->session_keyring;
138 task_unlock(current);
139 128
140 key_put(old); 129 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
141 } 130 KEY_ALLOC_QUOTA_OVERRUN, NULL);
142#endif 131 if (IS_ERR(keyring))
132 return PTR_ERR(keyring);
143 133
144} /* end switch_uid_keyring() */ 134 new->thread_keyring = keyring;
135 return 0;
136}
145 137
146/*****************************************************************************/
147/* 138/*
148 * install a fresh thread keyring, discarding the old one 139 * install a fresh thread keyring, discarding the old one
149 */ 140 */
150int install_thread_keyring(void) 141static int install_thread_keyring(void)
151{ 142{
152 struct task_struct *tsk = current; 143 struct cred *new;
153 struct key *keyring, *old;
154 char buf[20];
155 int ret; 144 int ret;
156 145
157 sprintf(buf, "_tid.%u", tsk->pid); 146 new = prepare_creds();
147 if (!new)
148 return -ENOMEM;
158 149
159 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk, 150 BUG_ON(new->thread_keyring);
160 KEY_ALLOC_QUOTA_OVERRUN, NULL); 151
161 if (IS_ERR(keyring)) { 152 ret = install_thread_keyring_to_cred(new);
162 ret = PTR_ERR(keyring); 153 if (ret < 0) {
163 goto error; 154 abort_creds(new);
155 return ret;
164 } 156 }
165 157
166 task_lock(tsk); 158 return commit_creds(new);
167 old = tsk->cred->thread_keyring; 159}
168 tsk->cred->thread_keyring = keyring;
169 task_unlock(tsk);
170 160
171 ret = 0; 161/*
162 * install a process keyring directly to a credentials struct
163 * - returns -EEXIST if there was already a process keyring, 0 if one installed,
164 * and other -ve on any other error
165 */
166int install_process_keyring_to_cred(struct cred *new)
167{
168 struct key *keyring;
169 int ret;
172 170
173 key_put(old); 171 if (new->tgcred->process_keyring)
174error: 172 return -EEXIST;
173
174 keyring = keyring_alloc("_pid", new->uid, new->gid,
175 new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
176 if (IS_ERR(keyring))
177 return PTR_ERR(keyring);
178
179 spin_lock_irq(&new->tgcred->lock);
180 if (!new->tgcred->process_keyring) {
181 new->tgcred->process_keyring = keyring;
182 keyring = NULL;
183 ret = 0;
184 } else {
185 ret = -EEXIST;
186 }
187 spin_unlock_irq(&new->tgcred->lock);
188 key_put(keyring);
175 return ret; 189 return ret;
190}
176 191
177} /* end install_thread_keyring() */
178
179/*****************************************************************************/
180/* 192/*
181 * make sure a process keyring is installed 193 * make sure a process keyring is installed
194 * - we
182 */ 195 */
183int install_process_keyring(void) 196static int install_process_keyring(void)
184{ 197{
185 struct task_struct *tsk = current; 198 struct cred *new;
186 struct key *keyring;
187 char buf[20];
188 int ret; 199 int ret;
189 200
190 might_sleep(); 201 new = prepare_creds();
191 202 if (!new)
192 if (!tsk->cred->tgcred->process_keyring) { 203 return -ENOMEM;
193 sprintf(buf, "_pid.%u", tsk->tgid);
194
195 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
196 KEY_ALLOC_QUOTA_OVERRUN, NULL);
197 if (IS_ERR(keyring)) {
198 ret = PTR_ERR(keyring);
199 goto error;
200 }
201
202 /* attach keyring */
203 spin_lock_irq(&tsk->cred->tgcred->lock);
204 if (!tsk->cred->tgcred->process_keyring) {
205 tsk->cred->tgcred->process_keyring = keyring;
206 keyring = NULL;
207 }
208 spin_unlock_irq(&tsk->cred->tgcred->lock);
209 204
210 key_put(keyring); 205 ret = install_process_keyring_to_cred(new);
206 if (ret < 0) {
207 abort_creds(new);
208 return ret != -EEXIST ?: 0;
211 } 209 }
212 210
213 ret = 0; 211 return commit_creds(new);
214error: 212}
215 return ret;
216
217} /* end install_process_keyring() */
218 213
219/*****************************************************************************/
220/* 214/*
221 * install a session keyring, discarding the old one 215 * install a session keyring directly to a credentials struct
222 * - if a keyring is not supplied, an empty one is invented
223 */ 216 */
224static int install_session_keyring(struct key *keyring) 217static int install_session_keyring_to_cred(struct cred *cred,
218 struct key *keyring)
225{ 219{
226 struct task_struct *tsk = current;
227 unsigned long flags; 220 unsigned long flags;
228 struct key *old; 221 struct key *old;
229 char buf[20];
230 222
231 might_sleep(); 223 might_sleep();
232 224
233 /* create an empty session keyring */ 225 /* create an empty session keyring */
234 if (!keyring) { 226 if (!keyring) {
235 sprintf(buf, "_ses.%u", tsk->tgid);
236
237 flags = KEY_ALLOC_QUOTA_OVERRUN; 227 flags = KEY_ALLOC_QUOTA_OVERRUN;
238 if (tsk->cred->tgcred->session_keyring) 228 if (cred->tgcred->session_keyring)
239 flags = KEY_ALLOC_IN_QUOTA; 229 flags = KEY_ALLOC_IN_QUOTA;
240 230
241 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, 231 keyring = keyring_alloc("_ses", cred->uid, cred->gid,
242 tsk, flags, NULL); 232 cred, flags, NULL);
243 if (IS_ERR(keyring)) 233 if (IS_ERR(keyring))
244 return PTR_ERR(keyring); 234 return PTR_ERR(keyring);
245 } 235 } else {
246 else {
247 atomic_inc(&keyring->usage); 236 atomic_inc(&keyring->usage);
248 } 237 }
249 238
250 /* install the keyring */ 239 /* install the keyring */
251 spin_lock_irq(&tsk->cred->tgcred->lock); 240 spin_lock_irq(&cred->tgcred->lock);
252 old = tsk->cred->tgcred->session_keyring; 241 old = cred->tgcred->session_keyring;
253 rcu_assign_pointer(tsk->cred->tgcred->session_keyring, keyring); 242 rcu_assign_pointer(cred->tgcred->session_keyring, keyring);
254 spin_unlock_irq(&tsk->cred->tgcred->lock); 243 spin_unlock_irq(&cred->tgcred->lock);
255 244
256 /* we're using RCU on the pointer, but there's no point synchronising 245 /* we're using RCU on the pointer, but there's no point synchronising
257 * on it if it didn't previously point to anything */ 246 * on it if it didn't previously point to anything */
@@ -261,38 +250,29 @@ static int install_session_keyring(struct key *keyring)
261 } 250 }
262 251
263 return 0; 252 return 0;
253}
264 254
265} /* end install_session_keyring() */
266
267/*****************************************************************************/
268/* 255/*
269 * copy the keys for fork 256 * install a session keyring, discarding the old one
257 * - if a keyring is not supplied, an empty one is invented
270 */ 258 */
271int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 259static int install_session_keyring(struct key *keyring)
272{ 260{
273 key_check(tsk->cred->thread_keyring); 261 struct cred *new;
274 key_check(tsk->cred->request_key_auth); 262 int ret;
275
276 /* no thread keyring yet */
277 tsk->cred->thread_keyring = NULL;
278
279 /* copy the request_key() authorisation for this thread */
280 key_get(tsk->cred->request_key_auth);
281
282 return 0;
283 263
284} /* end copy_keys() */ 264 new = prepare_creds();
265 if (!new)
266 return -ENOMEM;
285 267
286/*****************************************************************************/ 268 ret = install_session_keyring_to_cred(new, NULL);
287/* 269 if (ret < 0) {
288 * dispose of per-thread keys upon thread exit 270 abort_creds(new);
289 */ 271 return ret;
290void exit_keys(struct task_struct *tsk) 272 }
291{
292 key_put(tsk->cred->thread_keyring);
293 key_put(tsk->cred->request_key_auth);
294 273
295} /* end exit_keys() */ 274 return commit_creds(new);
275}
296 276
297/*****************************************************************************/ 277/*****************************************************************************/
298/* 278/*
@@ -300,38 +280,41 @@ void exit_keys(struct task_struct *tsk)
300 */ 280 */
301int exec_keys(struct task_struct *tsk) 281int exec_keys(struct task_struct *tsk)
302{ 282{
303 struct key *old; 283 struct thread_group_cred *tgcred = NULL;
284 struct cred *new;
304 285
305 /* newly exec'd tasks don't get a thread keyring */ 286#ifdef CONFIG_KEYS
306 task_lock(tsk); 287 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
307 old = tsk->cred->thread_keyring; 288 if (!tgcred)
308 tsk->cred->thread_keyring = NULL; 289 return -ENOMEM;
309 task_unlock(tsk); 290#endif
310 291
311 key_put(old); 292 new = prepare_creds();
293 if (new < 0)
294 return -ENOMEM;
312 295
313 /* discard the process keyring from a newly exec'd task */ 296 /* newly exec'd tasks don't get a thread keyring */
314 spin_lock_irq(&tsk->cred->tgcred->lock); 297 key_put(new->thread_keyring);
315 old = tsk->cred->tgcred->process_keyring; 298 new->thread_keyring = NULL;
316 tsk->cred->tgcred->process_keyring = NULL;
317 spin_unlock_irq(&tsk->cred->tgcred->lock);
318 299
319 key_put(old); 300 /* create a new per-thread-group creds for all this set of threads to
301 * share */
302 memcpy(tgcred, new->tgcred, sizeof(struct thread_group_cred));
320 303
321 return 0; 304 atomic_set(&tgcred->usage, 1);
305 spin_lock_init(&tgcred->lock);
322 306
323} /* end exec_keys() */ 307 /* inherit the session keyring; new process keyring */
308 key_get(tgcred->session_keyring);
309 tgcred->process_keyring = NULL;
324 310
325/*****************************************************************************/ 311 release_tgcred(new);
326/* 312 new->tgcred = tgcred;
327 * deal with SUID programs 313
328 * - we might want to make this invent a new session keyring 314 commit_creds(new);
329 */
330int suid_keys(struct task_struct *tsk)
331{
332 return 0; 315 return 0;
333 316
334} /* end suid_keys() */ 317} /* end exec_keys() */
335 318
336/*****************************************************************************/ 319/*****************************************************************************/
337/* 320/*
@@ -376,16 +359,13 @@ void key_fsgid_changed(struct task_struct *tsk)
376key_ref_t search_process_keyrings(struct key_type *type, 359key_ref_t search_process_keyrings(struct key_type *type,
377 const void *description, 360 const void *description,
378 key_match_func_t match, 361 key_match_func_t match,
379 struct task_struct *context) 362 const struct cred *cred)
380{ 363{
381 struct request_key_auth *rka; 364 struct request_key_auth *rka;
382 struct cred *cred;
383 key_ref_t key_ref, ret, err; 365 key_ref_t key_ref, ret, err;
384 366
385 might_sleep(); 367 might_sleep();
386 368
387 cred = get_task_cred(context);
388
389 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 369 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
390 * searchable, but we failed to find a key or we found a negative key; 370 * searchable, but we failed to find a key or we found a negative key;
391 * otherwise we want to return a sample error (probably -EACCES) if 371 * otherwise we want to return a sample error (probably -EACCES) if
@@ -401,7 +381,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
401 if (cred->thread_keyring) { 381 if (cred->thread_keyring) {
402 key_ref = keyring_search_aux( 382 key_ref = keyring_search_aux(
403 make_key_ref(cred->thread_keyring, 1), 383 make_key_ref(cred->thread_keyring, 1),
404 context, type, description, match); 384 cred, type, description, match);
405 if (!IS_ERR(key_ref)) 385 if (!IS_ERR(key_ref))
406 goto found; 386 goto found;
407 387
@@ -422,7 +402,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
422 if (cred->tgcred->process_keyring) { 402 if (cred->tgcred->process_keyring) {
423 key_ref = keyring_search_aux( 403 key_ref = keyring_search_aux(
424 make_key_ref(cred->tgcred->process_keyring, 1), 404 make_key_ref(cred->tgcred->process_keyring, 1),
425 context, type, description, match); 405 cred, type, description, match);
426 if (!IS_ERR(key_ref)) 406 if (!IS_ERR(key_ref))
427 goto found; 407 goto found;
428 408
@@ -446,7 +426,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
446 make_key_ref(rcu_dereference( 426 make_key_ref(rcu_dereference(
447 cred->tgcred->session_keyring), 427 cred->tgcred->session_keyring),
448 1), 428 1),
449 context, type, description, match); 429 cred, type, description, match);
450 rcu_read_unlock(); 430 rcu_read_unlock();
451 431
452 if (!IS_ERR(key_ref)) 432 if (!IS_ERR(key_ref))
@@ -468,7 +448,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
468 else if (cred->user->session_keyring) { 448 else if (cred->user->session_keyring) {
469 key_ref = keyring_search_aux( 449 key_ref = keyring_search_aux(
470 make_key_ref(cred->user->session_keyring, 1), 450 make_key_ref(cred->user->session_keyring, 1),
471 context, type, description, match); 451 cred, type, description, match);
472 if (!IS_ERR(key_ref)) 452 if (!IS_ERR(key_ref))
473 goto found; 453 goto found;
474 454
@@ -490,7 +470,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
490 * - we don't permit access to request_key auth keys via this method 470 * - we don't permit access to request_key auth keys via this method
491 */ 471 */
492 if (cred->request_key_auth && 472 if (cred->request_key_auth &&
493 context == current && 473 cred == current_cred() &&
494 type != &key_type_request_key_auth 474 type != &key_type_request_key_auth
495 ) { 475 ) {
496 /* defend against the auth key being revoked */ 476 /* defend against the auth key being revoked */
@@ -500,7 +480,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
500 rka = cred->request_key_auth->payload.data; 480 rka = cred->request_key_auth->payload.data;
501 481
502 key_ref = search_process_keyrings(type, description, 482 key_ref = search_process_keyrings(type, description,
503 match, rka->context); 483 match, rka->cred);
504 484
505 up_read(&cred->request_key_auth->sem); 485 up_read(&cred->request_key_auth->sem);
506 486
@@ -527,7 +507,6 @@ key_ref_t search_process_keyrings(struct key_type *type,
527 key_ref = ret ? ret : err; 507 key_ref = ret ? ret : err;
528 508
529found: 509found:
530 put_cred(cred);
531 return key_ref; 510 return key_ref;
532 511
533} /* end search_process_keyrings() */ 512} /* end search_process_keyrings() */
@@ -552,8 +531,7 @@ key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
552 key_perm_t perm) 531 key_perm_t perm)
553{ 532{
554 struct request_key_auth *rka; 533 struct request_key_auth *rka;
555 struct task_struct *t = current; 534 const struct cred *cred;
556 struct cred *cred;
557 struct key *key; 535 struct key *key;
558 key_ref_t key_ref, skey_ref; 536 key_ref_t key_ref, skey_ref;
559 int ret; 537 int ret;
@@ -608,6 +586,7 @@ try_again:
608 goto error; 586 goto error;
609 ret = install_session_keyring( 587 ret = install_session_keyring(
610 cred->user->session_keyring); 588 cred->user->session_keyring);
589
611 if (ret < 0) 590 if (ret < 0)
612 goto error; 591 goto error;
613 goto reget_creds; 592 goto reget_creds;
@@ -693,7 +672,7 @@ try_again:
693 /* check to see if we possess the key */ 672 /* check to see if we possess the key */
694 skey_ref = search_process_keyrings(key->type, key, 673 skey_ref = search_process_keyrings(key->type, key,
695 lookup_user_key_possessed, 674 lookup_user_key_possessed,
696 current); 675 cred);
697 676
698 if (!IS_ERR(skey_ref)) { 677 if (!IS_ERR(skey_ref)) {
699 key_put(key); 678 key_put(key);
@@ -725,7 +704,7 @@ try_again:
725 goto invalid_key; 704 goto invalid_key;
726 705
727 /* check the permissions */ 706 /* check the permissions */
728 ret = key_task_permission(key_ref, t, perm); 707 ret = key_task_permission(key_ref, cred, perm);
729 if (ret < 0) 708 if (ret < 0)
730 goto invalid_key; 709 goto invalid_key;
731 710
@@ -755,21 +734,33 @@ reget_creds:
755 */ 734 */
756long join_session_keyring(const char *name) 735long join_session_keyring(const char *name)
757{ 736{
758 struct task_struct *tsk = current; 737 const struct cred *old;
759 struct cred *cred = current->cred; 738 struct cred *new;
760 struct key *keyring; 739 struct key *keyring;
761 long ret; 740 long ret, serial;
741
742 /* only permit this if there's a single thread in the thread group -
743 * this avoids us having to adjust the creds on all threads and risking
744 * ENOMEM */
745 if (!is_single_threaded(current))
746 return -EMLINK;
747
748 new = prepare_creds();
749 if (!new)
750 return -ENOMEM;
751 old = current_cred();
762 752
763 /* if no name is provided, install an anonymous keyring */ 753 /* if no name is provided, install an anonymous keyring */
764 if (!name) { 754 if (!name) {
765 ret = install_session_keyring(NULL); 755 ret = install_session_keyring_to_cred(new, NULL);
766 if (ret < 0) 756 if (ret < 0)
767 goto error; 757 goto error;
768 758
769 rcu_read_lock(); 759 serial = new->tgcred->session_keyring->serial;
770 ret = rcu_dereference(cred->tgcred->session_keyring)->serial; 760 ret = commit_creds(new);
771 rcu_read_unlock(); 761 if (ret == 0)
772 goto error; 762 ret = serial;
763 goto okay;
773 } 764 }
774 765
775 /* allow the user to join or create a named keyring */ 766 /* allow the user to join or create a named keyring */
@@ -779,29 +770,33 @@ long join_session_keyring(const char *name)
779 keyring = find_keyring_by_name(name, false); 770 keyring = find_keyring_by_name(name, false);
780 if (PTR_ERR(keyring) == -ENOKEY) { 771 if (PTR_ERR(keyring) == -ENOKEY) {
781 /* not found - try and create a new one */ 772 /* not found - try and create a new one */
782 keyring = keyring_alloc(name, cred->uid, cred->gid, tsk, 773 keyring = keyring_alloc(name, old->uid, old->gid, old,
783 KEY_ALLOC_IN_QUOTA, NULL); 774 KEY_ALLOC_IN_QUOTA, NULL);
784 if (IS_ERR(keyring)) { 775 if (IS_ERR(keyring)) {
785 ret = PTR_ERR(keyring); 776 ret = PTR_ERR(keyring);
786 goto error2; 777 goto error2;
787 } 778 }
788 } 779 } else if (IS_ERR(keyring)) {
789 else if (IS_ERR(keyring)) {
790 ret = PTR_ERR(keyring); 780 ret = PTR_ERR(keyring);
791 goto error2; 781 goto error2;
792 } 782 }
793 783
794 /* we've got a keyring - now to install it */ 784 /* we've got a keyring - now to install it */
795 ret = install_session_keyring(keyring); 785 ret = install_session_keyring_to_cred(new, keyring);
796 if (ret < 0) 786 if (ret < 0)
797 goto error2; 787 goto error2;
798 788
789 commit_creds(new);
790 mutex_unlock(&key_session_mutex);
791
799 ret = keyring->serial; 792 ret = keyring->serial;
800 key_put(keyring); 793 key_put(keyring);
794okay:
795 return ret;
801 796
802error2: 797error2:
803 mutex_unlock(&key_session_mutex); 798 mutex_unlock(&key_session_mutex);
804error: 799error:
800 abort_creds(new);
805 return ret; 801 return ret;
806 802}
807} /* end join_session_keyring() */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 3d12558362df..0e04f72ef2d4 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -83,8 +83,10 @@ static int call_sbin_request_key(struct key_construction *cons,
83 /* allocate a new session keyring */ 83 /* allocate a new session keyring */
84 sprintf(desc, "_req.%u", key->serial); 84 sprintf(desc, "_req.%u", key->serial);
85 85
86 keyring = keyring_alloc(desc, current_fsuid(), current_fsgid(), current, 86 cred = get_current_cred();
87 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
87 KEY_ALLOC_QUOTA_OVERRUN, NULL); 88 KEY_ALLOC_QUOTA_OVERRUN, NULL);
89 put_cred(cred);
88 if (IS_ERR(keyring)) { 90 if (IS_ERR(keyring)) {
89 ret = PTR_ERR(keyring); 91 ret = PTR_ERR(keyring);
90 goto error_alloc; 92 goto error_alloc;
@@ -104,8 +106,7 @@ static int call_sbin_request_key(struct key_construction *cons,
104 106
105 /* we specify the process's default keyrings */ 107 /* we specify the process's default keyrings */
106 sprintf(keyring_str[0], "%d", 108 sprintf(keyring_str[0], "%d",
107 cred->thread_keyring ? 109 cred->thread_keyring ? cred->thread_keyring->serial : 0);
108 cred->thread_keyring->serial : 0);
109 110
110 prkey = 0; 111 prkey = 0;
111 if (cred->tgcred->process_keyring) 112 if (cred->tgcred->process_keyring)
@@ -155,8 +156,8 @@ error_link:
155 key_put(keyring); 156 key_put(keyring);
156 157
157error_alloc: 158error_alloc:
158 kleave(" = %d", ret);
159 complete_request_key(cons, ret); 159 complete_request_key(cons, ret);
160 kleave(" = %d", ret);
160 return ret; 161 return ret;
161} 162}
162 163
@@ -295,6 +296,7 @@ static int construct_alloc_key(struct key_type *type,
295 struct key_user *user, 296 struct key_user *user,
296 struct key **_key) 297 struct key **_key)
297{ 298{
299 const struct cred *cred = current_cred();
298 struct key *key; 300 struct key *key;
299 key_ref_t key_ref; 301 key_ref_t key_ref;
300 302
@@ -302,9 +304,8 @@ static int construct_alloc_key(struct key_type *type,
302 304
303 mutex_lock(&user->cons_lock); 305 mutex_lock(&user->cons_lock);
304 306
305 key = key_alloc(type, description, 307 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
306 current_fsuid(), current_fsgid(), current, KEY_POS_ALL, 308 KEY_POS_ALL, flags);
307 flags);
308 if (IS_ERR(key)) 309 if (IS_ERR(key))
309 goto alloc_failed; 310 goto alloc_failed;
310 311
@@ -317,8 +318,7 @@ static int construct_alloc_key(struct key_type *type,
317 * waited for locks */ 318 * waited for locks */
318 mutex_lock(&key_construction_mutex); 319 mutex_lock(&key_construction_mutex);
319 320
320 key_ref = search_process_keyrings(type, description, type->match, 321 key_ref = search_process_keyrings(type, description, type->match, cred);
321 current);
322 if (!IS_ERR(key_ref)) 322 if (!IS_ERR(key_ref))
323 goto key_already_present; 323 goto key_already_present;
324 324
@@ -363,6 +363,8 @@ static struct key *construct_key_and_link(struct key_type *type,
363 struct key *key; 363 struct key *key;
364 int ret; 364 int ret;
365 365
366 kenter("");
367
366 user = key_user_lookup(current_fsuid()); 368 user = key_user_lookup(current_fsuid());
367 if (!user) 369 if (!user)
368 return ERR_PTR(-ENOMEM); 370 return ERR_PTR(-ENOMEM);
@@ -376,17 +378,21 @@ static struct key *construct_key_and_link(struct key_type *type,
376 if (ret == 0) { 378 if (ret == 0) {
377 ret = construct_key(key, callout_info, callout_len, aux, 379 ret = construct_key(key, callout_info, callout_len, aux,
378 dest_keyring); 380 dest_keyring);
379 if (ret < 0) 381 if (ret < 0) {
382 kdebug("cons failed");
380 goto construction_failed; 383 goto construction_failed;
384 }
381 } 385 }
382 386
383 key_put(dest_keyring); 387 key_put(dest_keyring);
388 kleave(" = key %d", key_serial(key));
384 return key; 389 return key;
385 390
386construction_failed: 391construction_failed:
387 key_negate_and_link(key, key_negative_timeout, NULL, NULL); 392 key_negate_and_link(key, key_negative_timeout, NULL, NULL);
388 key_put(key); 393 key_put(key);
389 key_put(dest_keyring); 394 key_put(dest_keyring);
395 kleave(" = %d", ret);
390 return ERR_PTR(ret); 396 return ERR_PTR(ret);
391} 397}
392 398
@@ -405,6 +411,7 @@ struct key *request_key_and_link(struct key_type *type,
405 struct key *dest_keyring, 411 struct key *dest_keyring,
406 unsigned long flags) 412 unsigned long flags)
407{ 413{
414 const struct cred *cred = current_cred();
408 struct key *key; 415 struct key *key;
409 key_ref_t key_ref; 416 key_ref_t key_ref;
410 417
@@ -414,7 +421,7 @@ struct key *request_key_and_link(struct key_type *type,
414 421
415 /* search all the process keyrings for a key */ 422 /* search all the process keyrings for a key */
416 key_ref = search_process_keyrings(type, description, type->match, 423 key_ref = search_process_keyrings(type, description, type->match,
417 current); 424 cred);
418 425
419 if (!IS_ERR(key_ref)) { 426 if (!IS_ERR(key_ref)) {
420 key = key_ref_to_ptr(key_ref); 427 key = key_ref_to_ptr(key_ref);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 2125579d5d73..86747151ee5b 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -105,9 +105,9 @@ static void request_key_auth_revoke(struct key *key)
105 105
106 kenter("{%d}", key->serial); 106 kenter("{%d}", key->serial);
107 107
108 if (rka->context) { 108 if (rka->cred) {
109 put_task_struct(rka->context); 109 put_cred(rka->cred);
110 rka->context = NULL; 110 rka->cred = NULL;
111 } 111 }
112 112
113} /* end request_key_auth_revoke() */ 113} /* end request_key_auth_revoke() */
@@ -122,9 +122,9 @@ static void request_key_auth_destroy(struct key *key)
122 122
123 kenter("{%d}", key->serial); 123 kenter("{%d}", key->serial);
124 124
125 if (rka->context) { 125 if (rka->cred) {
126 put_task_struct(rka->context); 126 put_cred(rka->cred);
127 rka->context = NULL; 127 rka->cred = NULL;
128 } 128 }
129 129
130 key_put(rka->target_key); 130 key_put(rka->target_key);
@@ -143,6 +143,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
143 size_t callout_len, struct key *dest_keyring) 143 size_t callout_len, struct key *dest_keyring)
144{ 144{
145 struct request_key_auth *rka, *irka; 145 struct request_key_auth *rka, *irka;
146 const struct cred *cred = current->cred;
146 struct key *authkey = NULL; 147 struct key *authkey = NULL;
147 char desc[20]; 148 char desc[20];
148 int ret; 149 int ret;
@@ -164,28 +165,25 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
164 165
165 /* see if the calling process is already servicing the key request of 166 /* see if the calling process is already servicing the key request of
166 * another process */ 167 * another process */
167 if (current->cred->request_key_auth) { 168 if (cred->request_key_auth) {
168 /* it is - use that instantiation context here too */ 169 /* it is - use that instantiation context here too */
169 down_read(&current->cred->request_key_auth->sem); 170 down_read(&cred->request_key_auth->sem);
170 171
171 /* if the auth key has been revoked, then the key we're 172 /* if the auth key has been revoked, then the key we're
172 * servicing is already instantiated */ 173 * servicing is already instantiated */
173 if (test_bit(KEY_FLAG_REVOKED, 174 if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
174 &current->cred->request_key_auth->flags))
175 goto auth_key_revoked; 175 goto auth_key_revoked;
176 176
177 irka = current->cred->request_key_auth->payload.data; 177 irka = cred->request_key_auth->payload.data;
178 rka->context = irka->context; 178 rka->cred = get_cred(irka->cred);
179 rka->pid = irka->pid; 179 rka->pid = irka->pid;
180 get_task_struct(rka->context);
181 180
182 up_read(&current->cred->request_key_auth->sem); 181 up_read(&cred->request_key_auth->sem);
183 } 182 }
184 else { 183 else {
185 /* it isn't - use this process as the context */ 184 /* it isn't - use this process as the context */
186 rka->context = current; 185 rka->cred = get_cred(cred);
187 rka->pid = current->pid; 186 rka->pid = current->pid;
188 get_task_struct(rka->context);
189 } 187 }
190 188
191 rka->target_key = key_get(target); 189 rka->target_key = key_get(target);
@@ -197,7 +195,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
197 sprintf(desc, "%x", target->serial); 195 sprintf(desc, "%x", target->serial);
198 196
199 authkey = key_alloc(&key_type_request_key_auth, desc, 197 authkey = key_alloc(&key_type_request_key_auth, desc,
200 current_fsuid(), current_fsgid(), current, 198 cred->fsuid, cred->fsgid, cred,
201 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 199 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
202 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 200 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
203 if (IS_ERR(authkey)) { 201 if (IS_ERR(authkey)) {
@@ -205,16 +203,16 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
205 goto error_alloc; 203 goto error_alloc;
206 } 204 }
207 205
208 /* construct and attach to the keyring */ 206 /* construct the auth key */
209 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); 207 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
210 if (ret < 0) 208 if (ret < 0)
211 goto error_inst; 209 goto error_inst;
212 210
213 kleave(" = {%d}", authkey->serial); 211 kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage));
214 return authkey; 212 return authkey;
215 213
216auth_key_revoked: 214auth_key_revoked:
217 up_read(&current->cred->request_key_auth->sem); 215 up_read(&cred->request_key_auth->sem);
218 kfree(rka->callout_info); 216 kfree(rka->callout_info);
219 kfree(rka); 217 kfree(rka);
220 kleave("= -EKEYREVOKED"); 218 kleave("= -EKEYREVOKED");
@@ -257,6 +255,7 @@ static int key_get_instantiation_authkey_match(const struct key *key,
257 */ 255 */
258struct key *key_get_instantiation_authkey(key_serial_t target_id) 256struct key *key_get_instantiation_authkey(key_serial_t target_id)
259{ 257{
258 const struct cred *cred = current_cred();
260 struct key *authkey; 259 struct key *authkey;
261 key_ref_t authkey_ref; 260 key_ref_t authkey_ref;
262 261
@@ -264,7 +263,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
264 &key_type_request_key_auth, 263 &key_type_request_key_auth,
265 (void *) (unsigned long) target_id, 264 (void *) (unsigned long) target_id,
266 key_get_instantiation_authkey_match, 265 key_get_instantiation_authkey_match,
267 current); 266 cred);
268 267
269 if (IS_ERR(authkey_ref)) { 268 if (IS_ERR(authkey_ref)) {
270 authkey = ERR_CAST(authkey_ref); 269 authkey = ERR_CAST(authkey_ref);