aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/process_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r--security/keys/process_keys.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 217a0bef3c82..4d9825f9962c 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -67,7 +67,8 @@ struct key root_session_keyring = {
67/* 67/*
68 * allocate the keyrings to be associated with a UID 68 * allocate the keyrings to be associated with a UID
69 */ 69 */
70int alloc_uid_keyring(struct user_struct *user) 70int alloc_uid_keyring(struct user_struct *user,
71 struct task_struct *ctx)
71{ 72{
72 struct key *uid_keyring, *session_keyring; 73 struct key *uid_keyring, *session_keyring;
73 char buf[20]; 74 char buf[20];
@@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user)
76 /* concoct a default session keyring */ 77 /* concoct a default session keyring */
77 sprintf(buf, "_uid_ses.%u", user->uid); 78 sprintf(buf, "_uid_ses.%u", user->uid);
78 79
79 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL); 80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL);
80 if (IS_ERR(session_keyring)) { 81 if (IS_ERR(session_keyring)) {
81 ret = PTR_ERR(session_keyring); 82 ret = PTR_ERR(session_keyring);
82 goto error; 83 goto error;
@@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user)
86 * keyring */ 87 * keyring */
87 sprintf(buf, "_uid.%u", user->uid); 88 sprintf(buf, "_uid.%u", user->uid);
88 89
89 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, 90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0,
90 session_keyring); 91 session_keyring);
91 if (IS_ERR(uid_keyring)) { 92 if (IS_ERR(uid_keyring)) {
92 key_put(session_keyring); 93 key_put(session_keyring);
@@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk)
143 144
144 sprintf(buf, "_tid.%u", tsk->pid); 145 sprintf(buf, "_tid.%u", tsk->pid);
145 146
146 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
147 if (IS_ERR(keyring)) { 148 if (IS_ERR(keyring)) {
148 ret = PTR_ERR(keyring); 149 ret = PTR_ERR(keyring);
149 goto error; 150 goto error;
@@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk)
177 if (!tsk->signal->process_keyring) { 178 if (!tsk->signal->process_keyring) {
178 sprintf(buf, "_pid.%u", tsk->tgid); 179 sprintf(buf, "_pid.%u", tsk->tgid);
179 180
180 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 181 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
181 if (IS_ERR(keyring)) { 182 if (IS_ERR(keyring)) {
182 ret = PTR_ERR(keyring); 183 ret = PTR_ERR(keyring);
183 goto error; 184 goto error;
@@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk,
217 if (!keyring) { 218 if (!keyring) {
218 sprintf(buf, "_ses.%u", tsk->tgid); 219 sprintf(buf, "_ses.%u", tsk->tgid);
219 220
220 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 221 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
221 if (IS_ERR(keyring)) 222 if (IS_ERR(keyring))
222 return PTR_ERR(keyring); 223 return PTR_ERR(keyring);
223 } 224 }
@@ -390,6 +391,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
390 struct request_key_auth *rka; 391 struct request_key_auth *rka;
391 key_ref_t key_ref, ret, err; 392 key_ref_t key_ref, ret, err;
392 393
394 might_sleep();
395
393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 396 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 * searchable, but we failed to find a key or we found a negative key; 397 * searchable, but we failed to find a key or we found a negative key;
395 * otherwise we want to return a sample error (probably -EACCES) if 398 * otherwise we want to return a sample error (probably -EACCES) if
@@ -495,27 +498,35 @@ key_ref_t search_process_keyrings(struct key_type *type,
495 */ 498 */
496 if (context->request_key_auth && 499 if (context->request_key_auth &&
497 context == current && 500 context == current &&
498 type != &key_type_request_key_auth && 501 type != &key_type_request_key_auth
499 key_validate(context->request_key_auth) == 0
500 ) { 502 ) {
501 rka = context->request_key_auth->payload.data; 503 /* defend against the auth key being revoked */
504 down_read(&context->request_key_auth->sem);
502 505
503 key_ref = search_process_keyrings(type, description, match, 506 if (key_validate(context->request_key_auth) == 0) {
504 rka->context); 507 rka = context->request_key_auth->payload.data;
505 508
506 if (!IS_ERR(key_ref)) 509 key_ref = search_process_keyrings(type, description,
507 goto found; 510 match, rka->context);
508 511
509 switch (PTR_ERR(key_ref)) { 512 up_read(&context->request_key_auth->sem);
510 case -EAGAIN: /* no key */ 513
511 if (ret) 514 if (!IS_ERR(key_ref))
515 goto found;
516
517 switch (PTR_ERR(key_ref)) {
518 case -EAGAIN: /* no key */
519 if (ret)
520 break;
521 case -ENOKEY: /* negative key */
522 ret = key_ref;
512 break; 523 break;
513 case -ENOKEY: /* negative key */ 524 default:
514 ret = key_ref; 525 err = key_ref;
515 break; 526 break;
516 default: 527 }
517 err = key_ref; 528 } else {
518 break; 529 up_read(&context->request_key_auth->sem);
519 } 530 }
520 } 531 }
521 532
@@ -717,7 +728,7 @@ long join_session_keyring(const char *name)
717 keyring = find_keyring_by_name(name, 0); 728 keyring = find_keyring_by_name(name, 0);
718 if (PTR_ERR(keyring) == -ENOKEY) { 729 if (PTR_ERR(keyring) == -ENOKEY) {
719 /* not found - try and create a new one */ 730 /* not found - try and create a new one */
720 keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); 731 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
721 if (IS_ERR(keyring)) { 732 if (IS_ERR(keyring)) {
722 ret = PTR_ERR(keyring); 733 ret = PTR_ERR(keyring);
723 goto error2; 734 goto error2;