aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Makefile5
-rw-r--r--security/keys/compat.c7
-rw-r--r--security/keys/internal.h45
-rw-r--r--security/keys/key.c24
-rw-r--r--security/keys/keyctl.c176
-rw-r--r--security/keys/keyring.c67
-rw-r--r--security/keys/process_keys.c179
-rw-r--r--security/keys/request_key.c182
-rw-r--r--security/keys/request_key_auth.c180
9 files changed, 685 insertions, 180 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
index ddb495d65062..c392d750b208 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -7,8 +7,9 @@ obj-y := \
7 keyring.o \ 7 keyring.o \
8 keyctl.o \ 8 keyctl.o \
9 process_keys.o \ 9 process_keys.o \
10 user_defined.o \ 10 request_key.o \
11 request_key.o 11 request_key_auth.o \
12 user_defined.o
12 13
13obj-$(CONFIG_KEYS_COMPAT) += compat.o 14obj-$(CONFIG_KEYS_COMPAT) += compat.o
14obj-$(CONFIG_PROC_FS) += proc.o 15obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/security/keys/compat.c b/security/keys/compat.c
index aff8b22dcb5c..3303673c636e 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -1,6 +1,6 @@
1/* compat.c: 32-bit compatibility syscall for 64-bit systems 1/* compat.c: 32-bit compatibility syscall for 64-bit systems
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
24 * - if you can, you should call sys_keyctl directly 24 * - if you can, you should call sys_keyctl directly
25 */ 25 */
26asmlinkage long compat_sys_keyctl(u32 option, 26asmlinkage long compat_sys_keyctl(u32 option,
27 u32 arg2, u32 arg3, u32 arg4, u32 arg5) 27 u32 arg2, u32 arg3, u32 arg4, u32 arg5)
28{ 28{
29 switch (option) { 29 switch (option) {
30 case KEYCTL_GET_KEYRING_ID: 30 case KEYCTL_GET_KEYRING_ID:
@@ -71,6 +71,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
71 case KEYCTL_NEGATE: 71 case KEYCTL_NEGATE:
72 return keyctl_negate_key(arg2, arg3, arg4); 72 return keyctl_negate_key(arg2, arg3, arg4);
73 73
74 case KEYCTL_SET_REQKEY_KEYRING:
75 return keyctl_set_reqkey_keyring(arg2);
76
74 default: 77 default:
75 return -EOPNOTSUPP; 78 return -EOPNOTSUPP;
76 } 79 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 67b2b93a7489..46c8602661c9 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -1,6 +1,6 @@
1/* internal.h: authentication token and access key management internal defs 1/* internal.h: authentication token and access key management internal defs
2 * 2 *
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -15,6 +15,16 @@
15#include <linux/key.h> 15#include <linux/key.h>
16#include <linux/key-ui.h> 16#include <linux/key-ui.h>
17 17
18#if 0
19#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a)
20#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a)
21#define kdebug(FMT, a...) printk(FMT"\n" , ## a)
22#else
23#define kenter(FMT, a...) do {} while(0)
24#define kleave(FMT, a...) do {} while(0)
25#define kdebug(FMT, a...) do {} while(0)
26#endif
27
18extern struct key_type key_type_dead; 28extern struct key_type key_type_dead;
19extern struct key_type key_type_user; 29extern struct key_type key_type_user;
20 30
@@ -66,20 +76,46 @@ extern struct key *__keyring_search_one(struct key *keyring,
66 const char *description, 76 const char *description,
67 key_perm_t perm); 77 key_perm_t perm);
68 78
79extern struct key *keyring_search_instkey(struct key *keyring,
80 key_serial_t target_id);
81
69typedef int (*key_match_func_t)(const struct key *, const void *); 82typedef int (*key_match_func_t)(const struct key *, const void *);
70 83
71extern struct key *keyring_search_aux(struct key *keyring, 84extern struct key *keyring_search_aux(struct key *keyring,
85 struct task_struct *tsk,
72 struct key_type *type, 86 struct key_type *type,
73 const void *description, 87 const void *description,
74 key_match_func_t match); 88 key_match_func_t match);
75 89
76extern struct key *search_process_keyrings_aux(struct key_type *type, 90extern struct key *search_process_keyrings(struct key_type *type,
77 const void *description, 91 const void *description,
78 key_match_func_t match); 92 key_match_func_t match,
93 struct task_struct *tsk);
79 94
80extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); 95extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
81 96
82extern int install_thread_keyring(struct task_struct *tsk); 97extern int install_thread_keyring(struct task_struct *tsk);
98extern int install_process_keyring(struct task_struct *tsk);
99
100extern struct key *request_key_and_link(struct key_type *type,
101 const char *description,
102 const char *callout_info,
103 struct key *dest_keyring);
104
105/*
106 * request_key authorisation
107 */
108struct request_key_auth {
109 struct key *target_key;
110 struct task_struct *context;
111 pid_t pid;
112};
113
114extern struct key_type key_type_request_key_auth;
115extern struct key *request_key_auth_new(struct key *target,
116 struct key **_rkakey);
117
118extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
83 119
84/* 120/*
85 * keyctl functions 121 * keyctl functions
@@ -100,6 +136,7 @@ extern long keyctl_setperm_key(key_serial_t, key_perm_t);
100extern long keyctl_instantiate_key(key_serial_t, const void __user *, 136extern long keyctl_instantiate_key(key_serial_t, const void __user *,
101 size_t, key_serial_t); 137 size_t, key_serial_t);
102extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
139extern long keyctl_set_reqkey_keyring(int);
103 140
104 141
105/* 142/*
diff --git a/security/keys/key.c b/security/keys/key.c
index 1fdfccb3fe43..3304d37bb379 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
1/* key.c: basic authentication token and access key management 1/* key.c: basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -391,7 +391,8 @@ EXPORT_SYMBOL(key_payload_reserve);
391static int __key_instantiate_and_link(struct key *key, 391static int __key_instantiate_and_link(struct key *key,
392 const void *data, 392 const void *data,
393 size_t datalen, 393 size_t datalen,
394 struct key *keyring) 394 struct key *keyring,
395 struct key *instkey)
395{ 396{
396 int ret, awaken; 397 int ret, awaken;
397 398
@@ -419,6 +420,10 @@ static int __key_instantiate_and_link(struct key *key,
419 /* and link it into the destination keyring */ 420 /* and link it into the destination keyring */
420 if (keyring) 421 if (keyring)
421 ret = __key_link(keyring, key); 422 ret = __key_link(keyring, key);
423
424 /* disable the authorisation key */
425 if (instkey)
426 key_revoke(instkey);
422 } 427 }
423 } 428 }
424 429
@@ -439,19 +444,21 @@ static int __key_instantiate_and_link(struct key *key,
439int key_instantiate_and_link(struct key *key, 444int key_instantiate_and_link(struct key *key,
440 const void *data, 445 const void *data,
441 size_t datalen, 446 size_t datalen,
442 struct key *keyring) 447 struct key *keyring,
448 struct key *instkey)
443{ 449{
444 int ret; 450 int ret;
445 451
446 if (keyring) 452 if (keyring)
447 down_write(&keyring->sem); 453 down_write(&keyring->sem);
448 454
449 ret = __key_instantiate_and_link(key, data, datalen, keyring); 455 ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);
450 456
451 if (keyring) 457 if (keyring)
452 up_write(&keyring->sem); 458 up_write(&keyring->sem);
453 459
454 return ret; 460 return ret;
461
455} /* end key_instantiate_and_link() */ 462} /* end key_instantiate_and_link() */
456 463
457EXPORT_SYMBOL(key_instantiate_and_link); 464EXPORT_SYMBOL(key_instantiate_and_link);
@@ -462,7 +469,8 @@ EXPORT_SYMBOL(key_instantiate_and_link);
462 */ 469 */
463int key_negate_and_link(struct key *key, 470int key_negate_and_link(struct key *key,
464 unsigned timeout, 471 unsigned timeout,
465 struct key *keyring) 472 struct key *keyring,
473 struct key *instkey)
466{ 474{
467 struct timespec now; 475 struct timespec now;
468 int ret, awaken; 476 int ret, awaken;
@@ -495,6 +503,10 @@ int key_negate_and_link(struct key *key,
495 /* and link it into the destination keyring */ 503 /* and link it into the destination keyring */
496 if (keyring) 504 if (keyring)
497 ret = __key_link(keyring, key); 505 ret = __key_link(keyring, key);
506
507 /* disable the authorisation key */
508 if (instkey)
509 key_revoke(instkey);
498 } 510 }
499 511
500 up_write(&key_construction_sem); 512 up_write(&key_construction_sem);
@@ -781,7 +793,7 @@ struct key *key_create_or_update(struct key *keyring,
781 } 793 }
782 794
783 /* instantiate it and link it into the target keyring */ 795 /* instantiate it and link it into the target keyring */
784 ret = __key_instantiate_and_link(key, payload, plen, keyring); 796 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
785 if (ret < 0) { 797 if (ret < 0) {
786 key_put(key); 798 key_put(key);
787 key = ERR_PTR(ret); 799 key = ERR_PTR(ret);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cedb7326de29..fea262860ea0 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1,6 +1,6 @@
1/* keyctl.c: userspace keyctl operations 1/* keyctl.c: userspace keyctl operations
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -49,6 +49,13 @@ asmlinkage long sys_add_key(const char __user *_type,
49 goto error; 49 goto error;
50 type[31] = '\0'; 50 type[31] = '\0';
51 51
52 if (!type[0])
53 goto error;
54
55 ret = -EPERM;
56 if (type[0] == '.')
57 goto error;
58
52 ret = -EFAULT; 59 ret = -EFAULT;
53 dlen = strnlen_user(_description, PAGE_SIZE - 1); 60 dlen = strnlen_user(_description, PAGE_SIZE - 1);
54 if (dlen <= 0) 61 if (dlen <= 0)
@@ -82,7 +89,7 @@ asmlinkage long sys_add_key(const char __user *_type,
82 } 89 }
83 90
84 /* find the target keyring (which must be writable) */ 91 /* find the target keyring (which must be writable) */
85 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 92 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
86 if (IS_ERR(keyring)) { 93 if (IS_ERR(keyring)) {
87 ret = PTR_ERR(keyring); 94 ret = PTR_ERR(keyring);
88 goto error3; 95 goto error3;
@@ -181,7 +188,7 @@ asmlinkage long sys_request_key(const char __user *_type,
181 /* get the destination keyring if specified */ 188 /* get the destination keyring if specified */
182 dest = NULL; 189 dest = NULL;
183 if (destringid) { 190 if (destringid) {
184 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 191 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
185 if (IS_ERR(dest)) { 192 if (IS_ERR(dest)) {
186 ret = PTR_ERR(dest); 193 ret = PTR_ERR(dest);
187 goto error3; 194 goto error3;
@@ -196,23 +203,15 @@ asmlinkage long sys_request_key(const char __user *_type,
196 } 203 }
197 204
198 /* do the search */ 205 /* do the search */
199 key = request_key(ktype, description, callout_info); 206 key = request_key_and_link(ktype, description, callout_info, dest);
200 if (IS_ERR(key)) { 207 if (IS_ERR(key)) {
201 ret = PTR_ERR(key); 208 ret = PTR_ERR(key);
202 goto error5; 209 goto error5;
203 } 210 }
204 211
205 /* link the resulting key to the destination keyring */
206 if (dest) {
207 ret = key_link(dest, key);
208 if (ret < 0)
209 goto error6;
210 }
211
212 ret = key->serial; 212 ret = key->serial;
213 213
214 error6: 214 key_put(key);
215 key_put(key);
216 error5: 215 error5:
217 key_type_put(ktype); 216 key_type_put(ktype);
218 error4: 217 error4:
@@ -237,7 +236,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
237 struct key *key; 236 struct key *key;
238 long ret; 237 long ret;
239 238
240 key = lookup_user_key(id, create, 0, KEY_SEARCH); 239 key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
241 if (IS_ERR(key)) { 240 if (IS_ERR(key)) {
242 ret = PTR_ERR(key); 241 ret = PTR_ERR(key);
243 goto error; 242 goto error;
@@ -324,7 +323,7 @@ long keyctl_update_key(key_serial_t id,
324 } 323 }
325 324
326 /* find the target key (which must be writable) */ 325 /* find the target key (which must be writable) */
327 key = lookup_user_key(id, 0, 0, KEY_WRITE); 326 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
328 if (IS_ERR(key)) { 327 if (IS_ERR(key)) {
329 ret = PTR_ERR(key); 328 ret = PTR_ERR(key);
330 goto error2; 329 goto error2;
@@ -352,7 +351,7 @@ long keyctl_revoke_key(key_serial_t id)
352 struct key *key; 351 struct key *key;
353 long ret; 352 long ret;
354 353
355 key = lookup_user_key(id, 0, 0, KEY_WRITE); 354 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
356 if (IS_ERR(key)) { 355 if (IS_ERR(key)) {
357 ret = PTR_ERR(key); 356 ret = PTR_ERR(key);
358 goto error; 357 goto error;
@@ -378,7 +377,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
378 struct key *keyring; 377 struct key *keyring;
379 long ret; 378 long ret;
380 379
381 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 380 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
382 if (IS_ERR(keyring)) { 381 if (IS_ERR(keyring)) {
383 ret = PTR_ERR(keyring); 382 ret = PTR_ERR(keyring);
384 goto error; 383 goto error;
@@ -404,13 +403,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
404 struct key *keyring, *key; 403 struct key *keyring, *key;
405 long ret; 404 long ret;
406 405
407 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 406 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
408 if (IS_ERR(keyring)) { 407 if (IS_ERR(keyring)) {
409 ret = PTR_ERR(keyring); 408 ret = PTR_ERR(keyring);
410 goto error; 409 goto error;
411 } 410 }
412 411
413 key = lookup_user_key(id, 1, 0, KEY_LINK); 412 key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
414 if (IS_ERR(key)) { 413 if (IS_ERR(key)) {
415 ret = PTR_ERR(key); 414 ret = PTR_ERR(key);
416 goto error2; 415 goto error2;
@@ -438,13 +437,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
438 struct key *keyring, *key; 437 struct key *keyring, *key;
439 long ret; 438 long ret;
440 439
441 keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE); 440 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
442 if (IS_ERR(keyring)) { 441 if (IS_ERR(keyring)) {
443 ret = PTR_ERR(keyring); 442 ret = PTR_ERR(keyring);
444 goto error; 443 goto error;
445 } 444 }
446 445
447 key = lookup_user_key(id, 0, 0, 0); 446 key = lookup_user_key(NULL, id, 0, 0, 0);
448 if (IS_ERR(key)) { 447 if (IS_ERR(key)) {
449 ret = PTR_ERR(key); 448 ret = PTR_ERR(key);
450 goto error2; 449 goto error2;
@@ -475,16 +474,29 @@ long keyctl_describe_key(key_serial_t keyid,
475 char __user *buffer, 474 char __user *buffer,
476 size_t buflen) 475 size_t buflen)
477{ 476{
478 struct key *key; 477 struct key *key, *instkey;
479 char *tmpbuf; 478 char *tmpbuf;
480 long ret; 479 long ret;
481 480
482 key = lookup_user_key(keyid, 0, 1, KEY_VIEW); 481 key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
483 if (IS_ERR(key)) { 482 if (IS_ERR(key)) {
483 /* viewing a key under construction is permitted if we have the
484 * authorisation token handy */
485 if (PTR_ERR(key) == -EACCES) {
486 instkey = key_get_instantiation_authkey(keyid);
487 if (!IS_ERR(instkey)) {
488 key_put(instkey);
489 key = lookup_user_key(NULL, keyid, 0, 1, 0);
490 if (!IS_ERR(key))
491 goto okay;
492 }
493 }
494
484 ret = PTR_ERR(key); 495 ret = PTR_ERR(key);
485 goto error; 496 goto error;
486 } 497 }
487 498
499okay:
488 /* calculate how much description we're going to return */ 500 /* calculate how much description we're going to return */
489 ret = -ENOMEM; 501 ret = -ENOMEM;
490 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 502 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -568,7 +580,7 @@ long keyctl_keyring_search(key_serial_t ringid,
568 goto error2; 580 goto error2;
569 581
570 /* get the keyring at which to begin the search */ 582 /* get the keyring at which to begin the search */
571 keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH); 583 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
572 if (IS_ERR(keyring)) { 584 if (IS_ERR(keyring)) {
573 ret = PTR_ERR(keyring); 585 ret = PTR_ERR(keyring);
574 goto error2; 586 goto error2;
@@ -577,7 +589,7 @@ long keyctl_keyring_search(key_serial_t ringid,
577 /* get the destination keyring if specified */ 589 /* get the destination keyring if specified */
578 dest = NULL; 590 dest = NULL;
579 if (destringid) { 591 if (destringid) {
580 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 592 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
581 if (IS_ERR(dest)) { 593 if (IS_ERR(dest)) {
582 ret = PTR_ERR(dest); 594 ret = PTR_ERR(dest);
583 goto error3; 595 goto error3;
@@ -656,24 +668,23 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
656 long ret; 668 long ret;
657 669
658 /* find the key first */ 670 /* find the key first */
659 key = lookup_user_key(keyid, 0, 0, 0); 671 key = lookup_user_key(NULL, keyid, 0, 0, 0);
660 if (!IS_ERR(key)) { 672 if (!IS_ERR(key)) {
661 /* see if we can read it directly */ 673 /* see if we can read it directly */
662 if (key_permission(key, KEY_READ)) 674 if (key_permission(key, KEY_READ))
663 goto can_read_key; 675 goto can_read_key;
664 676
665 /* can't; see if it's searchable from this process's 677 /* we can't; see if it's searchable from this process's
666 * keyrings */ 678 * keyrings
667 ret = -ENOKEY; 679 * - we automatically take account of the fact that it may be
668 if (key_permission(key, KEY_SEARCH)) { 680 * dangling off an instantiation key
669 /* okay - we do have search permission on the key 681 */
670 * itself, but do we have the key? */ 682 skey = search_process_keyrings(key->type, key,
671 skey = search_process_keyrings_aux(key->type, key, 683 keyctl_read_key_same, current);
672 keyctl_read_key_same); 684 if (!IS_ERR(skey))
673 if (!IS_ERR(skey)) 685 goto can_read_key2;
674 goto can_read_key2; 686
675 } 687 ret = PTR_ERR(skey);
676
677 goto error2; 688 goto error2;
678 } 689 }
679 690
@@ -719,7 +730,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
719 if (uid == (uid_t) -1 && gid == (gid_t) -1) 730 if (uid == (uid_t) -1 && gid == (gid_t) -1)
720 goto error; 731 goto error;
721 732
722 key = lookup_user_key(id, 1, 1, 0); 733 key = lookup_user_key(NULL, id, 1, 1, 0);
723 if (IS_ERR(key)) { 734 if (IS_ERR(key)) {
724 ret = PTR_ERR(key); 735 ret = PTR_ERR(key);
725 goto error; 736 goto error;
@@ -776,7 +787,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
776 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 787 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
777 goto error; 788 goto error;
778 789
779 key = lookup_user_key(id, 1, 1, 0); 790 key = lookup_user_key(NULL, id, 1, 1, 0);
780 if (IS_ERR(key)) { 791 if (IS_ERR(key)) {
781 ret = PTR_ERR(key); 792 ret = PTR_ERR(key);
782 goto error; 793 goto error;
@@ -809,7 +820,8 @@ long keyctl_instantiate_key(key_serial_t id,
809 size_t plen, 820 size_t plen,
810 key_serial_t ringid) 821 key_serial_t ringid)
811{ 822{
812 struct key *key, *keyring; 823 struct request_key_auth *rka;
824 struct key *instkey, *keyring;
813 void *payload; 825 void *payload;
814 long ret; 826 long ret;
815 827
@@ -831,18 +843,21 @@ long keyctl_instantiate_key(key_serial_t id,
831 goto error2; 843 goto error2;
832 } 844 }
833 845
834 /* find the target key (which must be writable) */ 846 /* find the instantiation authorisation key */
835 key = lookup_user_key(id, 0, 1, KEY_WRITE); 847 instkey = key_get_instantiation_authkey(id);
836 if (IS_ERR(key)) { 848 if (IS_ERR(instkey)) {
837 ret = PTR_ERR(key); 849 ret = PTR_ERR(instkey);
838 goto error2; 850 goto error2;
839 } 851 }
840 852
841 /* find the destination keyring if present (which must also be 853 rka = instkey->payload.data;
842 * writable) */ 854
855 /* find the destination keyring amongst those belonging to the
856 * requesting task */
843 keyring = NULL; 857 keyring = NULL;
844 if (ringid) { 858 if (ringid) {
845 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 859 keyring = lookup_user_key(rka->context, ringid, 1, 0,
860 KEY_WRITE);
846 if (IS_ERR(keyring)) { 861 if (IS_ERR(keyring)) {
847 ret = PTR_ERR(keyring); 862 ret = PTR_ERR(keyring);
848 goto error3; 863 goto error3;
@@ -850,11 +865,12 @@ long keyctl_instantiate_key(key_serial_t id,
850 } 865 }
851 866
852 /* instantiate the key and link it into a keyring */ 867 /* instantiate the key and link it into a keyring */
853 ret = key_instantiate_and_link(key, payload, plen, keyring); 868 ret = key_instantiate_and_link(rka->target_key, payload, plen,
869 keyring, instkey);
854 870
855 key_put(keyring); 871 key_put(keyring);
856 error3: 872 error3:
857 key_put(key); 873 key_put(instkey);
858 error2: 874 error2:
859 kfree(payload); 875 kfree(payload);
860 error: 876 error:
@@ -869,21 +885,24 @@ long keyctl_instantiate_key(key_serial_t id,
869 */ 885 */
870long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 886long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
871{ 887{
872 struct key *key, *keyring; 888 struct request_key_auth *rka;
889 struct key *instkey, *keyring;
873 long ret; 890 long ret;
874 891
875 /* find the target key (which must be writable) */ 892 /* find the instantiation authorisation key */
876 key = lookup_user_key(id, 0, 1, KEY_WRITE); 893 instkey = key_get_instantiation_authkey(id);
877 if (IS_ERR(key)) { 894 if (IS_ERR(instkey)) {
878 ret = PTR_ERR(key); 895 ret = PTR_ERR(instkey);
879 goto error; 896 goto error;
880 } 897 }
881 898
899 rka = instkey->payload.data;
900
882 /* find the destination keyring if present (which must also be 901 /* find the destination keyring if present (which must also be
883 * writable) */ 902 * writable) */
884 keyring = NULL; 903 keyring = NULL;
885 if (ringid) { 904 if (ringid) {
886 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 905 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
887 if (IS_ERR(keyring)) { 906 if (IS_ERR(keyring)) {
888 ret = PTR_ERR(keyring); 907 ret = PTR_ERR(keyring);
889 goto error2; 908 goto error2;
@@ -891,11 +910,11 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
891 } 910 }
892 911
893 /* instantiate the key and link it into a keyring */ 912 /* instantiate the key and link it into a keyring */
894 ret = key_negate_and_link(key, timeout, keyring); 913 ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
895 914
896 key_put(keyring); 915 key_put(keyring);
897 error2: 916 error2:
898 key_put(key); 917 key_put(instkey);
899 error: 918 error:
900 return ret; 919 return ret;
901 920
@@ -903,6 +922,44 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
903 922
904/*****************************************************************************/ 923/*****************************************************************************/
905/* 924/*
925 * set the default keyring in which request_key() will cache keys
926 * - return the old setting
927 */
928long keyctl_set_reqkey_keyring(int reqkey_defl)
929{
930 int ret;
931
932 switch (reqkey_defl) {
933 case KEY_REQKEY_DEFL_THREAD_KEYRING:
934 ret = install_thread_keyring(current);
935 if (ret < 0)
936 return ret;
937 goto set;
938
939 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
940 ret = install_process_keyring(current);
941 if (ret < 0)
942 return ret;
943
944 case KEY_REQKEY_DEFL_DEFAULT:
945 case KEY_REQKEY_DEFL_SESSION_KEYRING:
946 case KEY_REQKEY_DEFL_USER_KEYRING:
947 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
948 set:
949 current->jit_keyring = reqkey_defl;
950
951 case KEY_REQKEY_DEFL_NO_CHANGE:
952 return current->jit_keyring;
953
954 case KEY_REQKEY_DEFL_GROUP_KEYRING:
955 default:
956 return -EINVAL;
957 }
958
959} /* end keyctl_set_reqkey_keyring() */
960
961/*****************************************************************************/
962/*
906 * the key control system call 963 * the key control system call
907 */ 964 */
908asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 965asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -971,6 +1028,9 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
971 (unsigned) arg3, 1028 (unsigned) arg3,
972 (key_serial_t) arg4); 1029 (key_serial_t) arg4);
973 1030
1031 case KEYCTL_SET_REQKEY_KEYRING:
1032 return keyctl_set_reqkey_keyring(arg2);
1033
974 default: 1034 default:
975 return -EOPNOTSUPP; 1035 return -EOPNOTSUPP;
976 } 1036 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index c9a5de197487..90a551e4da66 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1,6 +1,6 @@
1/* keyring.c: keyring handling 1/* keyring.c: keyring handling
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -308,7 +308,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
308 uid, gid, KEY_USR_ALL, not_in_quota); 308 uid, gid, KEY_USR_ALL, not_in_quota);
309 309
310 if (!IS_ERR(keyring)) { 310 if (!IS_ERR(keyring)) {
311 ret = key_instantiate_and_link(keyring, NULL, 0, dest); 311 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
312 if (ret < 0) { 312 if (ret < 0) {
313 key_put(keyring); 313 key_put(keyring);
314 keyring = ERR_PTR(ret); 314 keyring = ERR_PTR(ret);
@@ -326,11 +326,12 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
326 * - we only find keys on which we have search permission 326 * - we only find keys on which we have search permission
327 * - we use the supplied match function to see if the description (or other 327 * - we use the supplied match function to see if the description (or other
328 * feature of interest) matches 328 * feature of interest) matches
329 * - we readlock the keyrings as we search down the tree 329 * - we rely on RCU to prevent the keyring lists from disappearing on us
330 * - we return -EAGAIN if we didn't find any matching key 330 * - we return -EAGAIN if we didn't find any matching key
331 * - we return -ENOKEY if we only found negative matching keys 331 * - we return -ENOKEY if we only found negative matching keys
332 */ 332 */
333struct key *keyring_search_aux(struct key *keyring, 333struct key *keyring_search_aux(struct key *keyring,
334 struct task_struct *context,
334 struct key_type *type, 335 struct key_type *type,
335 const void *description, 336 const void *description,
336 key_match_func_t match) 337 key_match_func_t match)
@@ -352,7 +353,7 @@ struct key *keyring_search_aux(struct key *keyring,
352 353
353 /* top keyring must have search permission to begin the search */ 354 /* top keyring must have search permission to begin the search */
354 key = ERR_PTR(-EACCES); 355 key = ERR_PTR(-EACCES);
355 if (!key_permission(keyring, KEY_SEARCH)) 356 if (!key_task_permission(keyring, context, KEY_SEARCH))
356 goto error; 357 goto error;
357 358
358 key = ERR_PTR(-ENOTDIR); 359 key = ERR_PTR(-ENOTDIR);
@@ -392,7 +393,7 @@ struct key *keyring_search_aux(struct key *keyring,
392 continue; 393 continue;
393 394
394 /* key must have search permissions */ 395 /* key must have search permissions */
395 if (!key_permission(key, KEY_SEARCH)) 396 if (!key_task_permission(key, context, KEY_SEARCH))
396 continue; 397 continue;
397 398
398 /* we set a different error code if we find a negative key */ 399 /* we set a different error code if we find a negative key */
@@ -418,7 +419,7 @@ struct key *keyring_search_aux(struct key *keyring,
418 if (sp >= KEYRING_SEARCH_MAX_DEPTH) 419 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
419 continue; 420 continue;
420 421
421 if (!key_permission(key, KEY_SEARCH)) 422 if (!key_task_permission(key, context, KEY_SEARCH))
422 continue; 423 continue;
423 424
424 /* stack the current position */ 425 /* stack the current position */
@@ -468,7 +469,11 @@ struct key *keyring_search(struct key *keyring,
468 struct key_type *type, 469 struct key_type *type,
469 const char *description) 470 const char *description)
470{ 471{
471 return keyring_search_aux(keyring, type, description, type->match); 472 if (!type->match)
473 return ERR_PTR(-ENOKEY);
474
475 return keyring_search_aux(keyring, current,
476 type, description, type->match);
472 477
473} /* end keyring_search() */ 478} /* end keyring_search() */
474 479
@@ -496,7 +501,8 @@ struct key *__keyring_search_one(struct key *keyring,
496 key = klist->keys[loop]; 501 key = klist->keys[loop];
497 502
498 if (key->type == ktype && 503 if (key->type == ktype &&
499 key->type->match(key, description) && 504 (!key->type->match ||
505 key->type->match(key, description)) &&
500 key_permission(key, perm) && 506 key_permission(key, perm) &&
501 !test_bit(KEY_FLAG_REVOKED, &key->flags) 507 !test_bit(KEY_FLAG_REVOKED, &key->flags)
502 ) 508 )
@@ -517,6 +523,51 @@ struct key *__keyring_search_one(struct key *keyring,
517 523
518/*****************************************************************************/ 524/*****************************************************************************/
519/* 525/*
526 * search for an instantiation authorisation key matching a target key
527 * - the RCU read lock must be held by the caller
528 * - a target_id of zero specifies any valid token
529 */
530struct key *keyring_search_instkey(struct key *keyring,
531 key_serial_t target_id)
532{
533 struct request_key_auth *rka;
534 struct keyring_list *klist;
535 struct key *instkey;
536 int loop;
537
538 klist = rcu_dereference(keyring->payload.subscriptions);
539 if (klist) {
540 for (loop = 0; loop < klist->nkeys; loop++) {
541 instkey = klist->keys[loop];
542
543 if (instkey->type != &key_type_request_key_auth)
544 continue;
545
546 rka = instkey->payload.data;
547 if (target_id && rka->target_key->serial != target_id)
548 continue;
549
550 /* the auth key is revoked during instantiation */
551 if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
552 goto found;
553
554 instkey = ERR_PTR(-EKEYREVOKED);
555 goto error;
556 }
557 }
558
559 instkey = ERR_PTR(-EACCES);
560 goto error;
561
562found:
563 atomic_inc(&instkey->usage);
564error:
565 return instkey;
566
567} /* end keyring_search_instkey() */
568
569/*****************************************************************************/
570/*
520 * find a keyring with the specified name 571 * find a keyring with the specified name
521 * - all named keyrings are searched 572 * - all named keyrings are searched
522 * - only find keyrings with search permission for the process 573 * - only find keyrings with search permission for the process
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 972e30172687..34db087bbcc7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -165,7 +165,7 @@ int install_thread_keyring(struct task_struct *tsk)
165/* 165/*
166 * make sure a process keyring is installed 166 * make sure a process keyring is installed
167 */ 167 */
168static int install_process_keyring(struct task_struct *tsk) 168int install_process_keyring(struct task_struct *tsk)
169{ 169{
170 unsigned long flags; 170 unsigned long flags;
171 struct key *keyring; 171 struct key *keyring;
@@ -376,12 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk)
376 * - we return -EAGAIN if we didn't find any matching key 376 * - we return -EAGAIN if we didn't find any matching key
377 * - we return -ENOKEY if we found only negative matching keys 377 * - we return -ENOKEY if we found only negative matching keys
378 */ 378 */
379struct key *search_process_keyrings_aux(struct key_type *type, 379struct key *search_process_keyrings(struct key_type *type,
380 const void *description, 380 const void *description,
381 key_match_func_t match) 381 key_match_func_t match,
382 struct task_struct *context)
382{ 383{
383 struct task_struct *tsk = current; 384 struct request_key_auth *rka;
384 struct key *key, *ret, *err; 385 struct key *key, *ret, *err, *instkey;
385 386
386 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
387 * searchable, but we failed to find a key or we found a negative key; 388 * searchable, but we failed to find a key or we found a negative key;
@@ -395,9 +396,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
395 err = ERR_PTR(-EAGAIN); 396 err = ERR_PTR(-EAGAIN);
396 397
397 /* search the thread keyring first */ 398 /* search the thread keyring first */
398 if (tsk->thread_keyring) { 399 if (context->thread_keyring) {
399 key = keyring_search_aux(tsk->thread_keyring, type, 400 key = keyring_search_aux(context->thread_keyring,
400 description, match); 401 context, type, description, match);
401 if (!IS_ERR(key)) 402 if (!IS_ERR(key))
402 goto found; 403 goto found;
403 404
@@ -415,9 +416,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
415 } 416 }
416 417
417 /* search the process keyring second */ 418 /* search the process keyring second */
418 if (tsk->signal->process_keyring) { 419 if (context->signal->process_keyring) {
419 key = keyring_search_aux(tsk->signal->process_keyring, 420 key = keyring_search_aux(context->signal->process_keyring,
420 type, description, match); 421 context, type, description, match);
421 if (!IS_ERR(key)) 422 if (!IS_ERR(key))
422 goto found; 423 goto found;
423 424
@@ -434,53 +435,93 @@ struct key *search_process_keyrings_aux(struct key_type *type,
434 } 435 }
435 } 436 }
436 437
437 /* search the session keyring last */ 438 /* search the session keyring */
438 if (tsk->signal->session_keyring) { 439 if (context->signal->session_keyring) {
439 rcu_read_lock(); 440 rcu_read_lock();
440 key = keyring_search_aux( 441 key = keyring_search_aux(
441 rcu_dereference(tsk->signal->session_keyring), 442 rcu_dereference(context->signal->session_keyring),
442 type, description, match); 443 context, type, description, match);
443 rcu_read_unlock(); 444 rcu_read_unlock();
445
446 if (!IS_ERR(key))
447 goto found;
448
449 switch (PTR_ERR(key)) {
450 case -EAGAIN: /* no key */
451 if (ret)
452 break;
453 case -ENOKEY: /* negative key */
454 ret = key;
455 break;
456 default:
457 err = key;
458 break;
459 }
460
461 /* if this process has a session keyring and that has an
462 * instantiation authorisation key in the bottom level, then we
463 * also search the keyrings of the process mentioned there */
464 if (context != current)
465 goto no_key;
466
467 rcu_read_lock();
468 instkey = __keyring_search_one(
469 rcu_dereference(context->signal->session_keyring),
470 &key_type_request_key_auth, NULL, 0);
471 rcu_read_unlock();
472
473 if (IS_ERR(instkey))
474 goto no_key;
475
476 rka = instkey->payload.data;
477
478 key = search_process_keyrings(type, description, match,
479 rka->context);
480 key_put(instkey);
481
482 if (!IS_ERR(key))
483 goto found;
484
485 switch (PTR_ERR(key)) {
486 case -EAGAIN: /* no key */
487 if (ret)
488 break;
489 case -ENOKEY: /* negative key */
490 ret = key;
491 break;
492 default:
493 err = key;
494 break;
495 }
444 } 496 }
497 /* or search the user-session keyring */
445 else { 498 else {
446 key = keyring_search_aux(tsk->user->session_keyring, 499 key = keyring_search_aux(context->user->session_keyring,
447 type, description, match); 500 context, type, description, match);
448 } 501 if (!IS_ERR(key))
449 502 goto found;
450 if (!IS_ERR(key))
451 goto found;
452 503
453 switch (PTR_ERR(key)) { 504 switch (PTR_ERR(key)) {
454 case -EAGAIN: /* no key */ 505 case -EAGAIN: /* no key */
455 if (ret) 506 if (ret)
507 break;
508 case -ENOKEY: /* negative key */
509 ret = key;
456 break; 510 break;
457 case -ENOKEY: /* negative key */ 511 default:
458 ret = key; 512 err = key;
459 break; 513 break;
460 default: 514 }
461 err = key;
462 break;
463 } 515 }
464 516
517
518no_key:
465 /* no key - decide on the error we're going to go for */ 519 /* no key - decide on the error we're going to go for */
466 key = ret ? ret : err; 520 key = ret ? ret : err;
467 521
468 found: 522found:
469 return key; 523 return key;
470 524
471} /* end search_process_keyrings_aux() */
472
473/*****************************************************************************/
474/*
475 * search the process keyrings for the first matching key
476 * - we return -EAGAIN if we didn't find any matching key
477 * - we return -ENOKEY if we found only negative matching keys
478 */
479struct key *search_process_keyrings(struct key_type *type,
480 const char *description)
481{
482 return search_process_keyrings_aux(type, description, type->match);
483
484} /* end search_process_keyrings() */ 525} /* end search_process_keyrings() */
485 526
486/*****************************************************************************/ 527/*****************************************************************************/
@@ -489,72 +530,73 @@ struct key *search_process_keyrings(struct key_type *type,
489 * - don't create special keyrings unless so requested 530 * - don't create special keyrings unless so requested
490 * - partially constructed keys aren't found unless requested 531 * - partially constructed keys aren't found unless requested
491 */ 532 */
492struct key *lookup_user_key(key_serial_t id, int create, int partial, 533struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
493 key_perm_t perm) 534 int create, int partial, key_perm_t perm)
494{ 535{
495 struct task_struct *tsk = current;
496 unsigned long flags;
497 struct key *key; 536 struct key *key;
498 int ret; 537 int ret;
499 538
539 if (!context)
540 context = current;
541
500 key = ERR_PTR(-ENOKEY); 542 key = ERR_PTR(-ENOKEY);
501 543
502 switch (id) { 544 switch (id) {
503 case KEY_SPEC_THREAD_KEYRING: 545 case KEY_SPEC_THREAD_KEYRING:
504 if (!tsk->thread_keyring) { 546 if (!context->thread_keyring) {
505 if (!create) 547 if (!create)
506 goto error; 548 goto error;
507 549
508 ret = install_thread_keyring(tsk); 550 ret = install_thread_keyring(context);
509 if (ret < 0) { 551 if (ret < 0) {
510 key = ERR_PTR(ret); 552 key = ERR_PTR(ret);
511 goto error; 553 goto error;
512 } 554 }
513 } 555 }
514 556
515 key = tsk->thread_keyring; 557 key = context->thread_keyring;
516 atomic_inc(&key->usage); 558 atomic_inc(&key->usage);
517 break; 559 break;
518 560
519 case KEY_SPEC_PROCESS_KEYRING: 561 case KEY_SPEC_PROCESS_KEYRING:
520 if (!tsk->signal->process_keyring) { 562 if (!context->signal->process_keyring) {
521 if (!create) 563 if (!create)
522 goto error; 564 goto error;
523 565
524 ret = install_process_keyring(tsk); 566 ret = install_process_keyring(context);
525 if (ret < 0) { 567 if (ret < 0) {
526 key = ERR_PTR(ret); 568 key = ERR_PTR(ret);
527 goto error; 569 goto error;
528 } 570 }
529 } 571 }
530 572
531 key = tsk->signal->process_keyring; 573 key = context->signal->process_keyring;
532 atomic_inc(&key->usage); 574 atomic_inc(&key->usage);
533 break; 575 break;
534 576
535 case KEY_SPEC_SESSION_KEYRING: 577 case KEY_SPEC_SESSION_KEYRING:
536 if (!tsk->signal->session_keyring) { 578 if (!context->signal->session_keyring) {
537 /* always install a session keyring upon access if one 579 /* always install a session keyring upon access if one
538 * doesn't exist yet */ 580 * doesn't exist yet */
539 ret = install_session_keyring( 581 ret = install_session_keyring(
540 tsk, tsk->user->session_keyring); 582 context, context->user->session_keyring);
541 if (ret < 0) 583 if (ret < 0)
542 goto error; 584 goto error;
543 } 585 }
544 586
545 spin_lock_irqsave(&tsk->sighand->siglock, flags); 587 rcu_read_lock();
546 key = tsk->signal->session_keyring; 588 key = rcu_dereference(context->signal->session_keyring);
547 atomic_inc(&key->usage); 589 atomic_inc(&key->usage);
548 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 590 rcu_read_unlock();
549 break; 591 break;
550 592
551 case KEY_SPEC_USER_KEYRING: 593 case KEY_SPEC_USER_KEYRING:
552 key = tsk->user->uid_keyring; 594 key = context->user->uid_keyring;
553 atomic_inc(&key->usage); 595 atomic_inc(&key->usage);
554 break; 596 break;
555 597
556 case KEY_SPEC_USER_SESSION_KEYRING: 598 case KEY_SPEC_USER_SESSION_KEYRING:
557 key = tsk->user->session_keyring; 599 key = context->user->session_keyring;
558 atomic_inc(&key->usage); 600 atomic_inc(&key->usage);
559 break; 601 break;
560 602
@@ -574,7 +616,7 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
574 break; 616 break;
575 } 617 }
576 618
577 /* check the status and permissions */ 619 /* check the status */
578 if (perm) { 620 if (perm) {
579 ret = key_validate(key); 621 ret = key_validate(key);
580 if (ret < 0) 622 if (ret < 0)
@@ -585,8 +627,10 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
585 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 627 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
586 goto invalid_key; 628 goto invalid_key;
587 629
630 /* check the permissions */
588 ret = -EACCES; 631 ret = -EACCES;
589 if (!key_permission(key, perm)) 632
633 if (!key_task_permission(key, context, perm))
590 goto invalid_key; 634 goto invalid_key;
591 635
592 error: 636 error:
@@ -609,7 +653,6 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
609long join_session_keyring(const char *name) 653long join_session_keyring(const char *name)
610{ 654{
611 struct task_struct *tsk = current; 655 struct task_struct *tsk = current;
612 unsigned long flags;
613 struct key *keyring; 656 struct key *keyring;
614 long ret; 657 long ret;
615 658
@@ -619,9 +662,9 @@ long join_session_keyring(const char *name)
619 if (ret < 0) 662 if (ret < 0)
620 goto error; 663 goto error;
621 664
622 spin_lock_irqsave(&tsk->sighand->siglock, flags); 665 rcu_read_lock();
623 ret = tsk->signal->session_keyring->serial; 666 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
624 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 667 rcu_read_unlock();
625 goto error; 668 goto error;
626 } 669 }
627 670
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 54aa7b70e63b..dfcd983af1fd 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,6 +1,6 @@
1/* request_key.c: request a key from userspace 1/* request_key.c: request a key from userspace
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/kmod.h> 14#include <linux/kmod.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/keyctl.h>
16#include "internal.h" 17#include "internal.h"
17 18
18struct key_construction { 19struct key_construction {
@@ -27,18 +28,26 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
27/* 28/*
28 * request userspace finish the construction of a key 29 * request userspace finish the construction of a key
29 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 30 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
30 * - if callout_info is an empty string, it'll be rendered as a "-" instead
31 */ 31 */
32static int call_request_key(struct key *key, 32static int call_request_key(struct key *key,
33 const char *op, 33 const char *op,
34 const char *callout_info) 34 const char *callout_info)
35{ 35{
36 struct task_struct *tsk = current; 36 struct task_struct *tsk = current;
37 unsigned long flags;
38 key_serial_t prkey, sskey; 37 key_serial_t prkey, sskey;
38 struct key *session_keyring, *rkakey;
39 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 39 char *argv[10], *envp[3], uid_str[12], gid_str[12];
40 char key_str[12], keyring_str[3][12]; 40 char key_str[12], keyring_str[3][12];
41 int i; 41 int ret, i;
42
43 kenter("{%d},%s,%s", key->serial, op, callout_info);
44
45 /* generate a new session keyring with an auth key in it */
46 session_keyring = request_key_auth_new(key, &rkakey);
47 if (IS_ERR(session_keyring)) {
48 ret = PTR_ERR(session_keyring);
49 goto error;
50 }
42 51
43 /* record the UID and GID */ 52 /* record the UID and GID */
44 sprintf(uid_str, "%d", current->fsuid); 53 sprintf(uid_str, "%d", current->fsuid);
@@ -55,17 +64,17 @@ static int call_request_key(struct key *key,
55 if (tsk->signal->process_keyring) 64 if (tsk->signal->process_keyring)
56 prkey = tsk->signal->process_keyring->serial; 65 prkey = tsk->signal->process_keyring->serial;
57 66
58 sskey = 0; 67 sprintf(keyring_str[1], "%d", prkey);
59 spin_lock_irqsave(&tsk->sighand->siglock, flags);
60 if (tsk->signal->session_keyring)
61 sskey = tsk->signal->session_keyring->serial;
62 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
63
64 68
65 if (!sskey) 69 if (tsk->signal->session_keyring) {
70 rcu_read_lock();
71 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
72 rcu_read_unlock();
73 }
74 else {
66 sskey = tsk->user->session_keyring->serial; 75 sskey = tsk->user->session_keyring->serial;
76 }
67 77
68 sprintf(keyring_str[1], "%d", prkey);
69 sprintf(keyring_str[2], "%d", sskey); 78 sprintf(keyring_str[2], "%d", sskey);
70 79
71 /* set up a minimal environment */ 80 /* set up a minimal environment */
@@ -84,11 +93,20 @@ static int call_request_key(struct key *key,
84 argv[i++] = keyring_str[0]; 93 argv[i++] = keyring_str[0];
85 argv[i++] = keyring_str[1]; 94 argv[i++] = keyring_str[1];
86 argv[i++] = keyring_str[2]; 95 argv[i++] = keyring_str[2];
87 argv[i++] = callout_info[0] ? (char *) callout_info : "-"; 96 argv[i++] = (char *) callout_info;
88 argv[i] = NULL; 97 argv[i] = NULL;
89 98
90 /* do it */ 99 /* do it */
91 return call_usermodehelper_keys(argv[0], argv, envp, NULL, 1); 100 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
101
102 /* dispose of the special keys */
103 key_revoke(rkakey);
104 key_put(rkakey);
105 key_put(session_keyring);
106
107 error:
108 kleave(" = %d", ret);
109 return ret;
92 110
93} /* end call_request_key() */ 111} /* end call_request_key() */
94 112
@@ -107,6 +125,8 @@ static struct key *__request_key_construction(struct key_type *type,
107 struct key *key; 125 struct key *key;
108 int ret, negated; 126 int ret, negated;
109 127
128 kenter("%s,%s,%s", type->name, description, callout_info);
129
110 /* create a key and add it to the queue */ 130 /* create a key and add it to the queue */
111 key = key_alloc(type, description, 131 key = key_alloc(type, description,
112 current->fsuid, current->fsgid, KEY_USR_ALL, 0); 132 current->fsuid, current->fsgid, KEY_USR_ALL, 0);
@@ -143,6 +163,7 @@ static struct key *__request_key_construction(struct key_type *type,
143 } 163 }
144 164
145 out: 165 out:
166 kleave(" = %p", key);
146 return key; 167 return key;
147 168
148 request_failed: 169 request_failed:
@@ -216,6 +237,9 @@ static struct key *request_key_construction(struct key_type *type,
216 237
217 DECLARE_WAITQUEUE(myself, current); 238 DECLARE_WAITQUEUE(myself, current);
218 239
240 kenter("%s,%s,{%d},%s",
241 type->name, description, user->uid, callout_info);
242
219 /* see if there's such a key under construction already */ 243 /* see if there's such a key under construction already */
220 down_write(&key_construction_sem); 244 down_write(&key_construction_sem);
221 245
@@ -232,6 +256,7 @@ static struct key *request_key_construction(struct key_type *type,
232 /* see about getting userspace to construct the key */ 256 /* see about getting userspace to construct the key */
233 key = __request_key_construction(type, description, callout_info); 257 key = __request_key_construction(type, description, callout_info);
234 error: 258 error:
259 kleave(" = %p", key);
235 return key; 260 return key;
236 261
237 /* someone else has the same key under construction 262 /* someone else has the same key under construction
@@ -245,9 +270,11 @@ static struct key *request_key_construction(struct key_type *type,
245 add_wait_queue(&request_key_conswq, &myself); 270 add_wait_queue(&request_key_conswq, &myself);
246 271
247 for (;;) { 272 for (;;) {
248 set_current_state(TASK_UNINTERRUPTIBLE); 273 set_current_state(TASK_INTERRUPTIBLE);
249 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags)) 274 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
250 break; 275 break;
276 if (signal_pending(current))
277 break;
251 schedule(); 278 schedule();
252 } 279 }
253 280
@@ -267,21 +294,83 @@ static struct key *request_key_construction(struct key_type *type,
267 294
268/*****************************************************************************/ 295/*****************************************************************************/
269/* 296/*
297 * link a freshly minted key to an appropriate destination keyring
298 */
299static void request_key_link(struct key *key, struct key *dest_keyring)
300{
301 struct task_struct *tsk = current;
302 struct key *drop = NULL;
303
304 kenter("{%d},%p", key->serial, dest_keyring);
305
306 /* find the appropriate keyring */
307 if (!dest_keyring) {
308 switch (tsk->jit_keyring) {
309 case KEY_REQKEY_DEFL_DEFAULT:
310 case KEY_REQKEY_DEFL_THREAD_KEYRING:
311 dest_keyring = tsk->thread_keyring;
312 if (dest_keyring)
313 break;
314
315 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
316 dest_keyring = tsk->signal->process_keyring;
317 if (dest_keyring)
318 break;
319
320 case KEY_REQKEY_DEFL_SESSION_KEYRING:
321 rcu_read_lock();
322 dest_keyring = key_get(
323 rcu_dereference(tsk->signal->session_keyring));
324 rcu_read_unlock();
325 drop = dest_keyring;
326
327 if (dest_keyring)
328 break;
329
330 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
331 dest_keyring = current->user->session_keyring;
332 break;
333
334 case KEY_REQKEY_DEFL_USER_KEYRING:
335 dest_keyring = current->user->uid_keyring;
336 break;
337
338 case KEY_REQKEY_DEFL_GROUP_KEYRING:
339 default:
340 BUG();
341 }
342 }
343
344 /* and attach the key to it */
345 key_link(dest_keyring, key);
346
347 key_put(drop);
348
349 kleave("");
350
351} /* end request_key_link() */
352
353/*****************************************************************************/
354/*
270 * request a key 355 * request a key
271 * - search the process's keyrings 356 * - search the process's keyrings
272 * - check the list of keys being created or updated 357 * - check the list of keys being created or updated
273 * - call out to userspace for a key if requested (supplementary info can be 358 * - call out to userspace for a key if supplementary info was provided
274 * passed) 359 * - cache the key in an appropriate keyring
275 */ 360 */
276struct key *request_key(struct key_type *type, 361struct key *request_key_and_link(struct key_type *type,
277 const char *description, 362 const char *description,
278 const char *callout_info) 363 const char *callout_info,
364 struct key *dest_keyring)
279{ 365{
280 struct key_user *user; 366 struct key_user *user;
281 struct key *key; 367 struct key *key;
282 368
369 kenter("%s,%s,%s,%p",
370 type->name, description, callout_info, dest_keyring);
371
283 /* search all the process keyrings for a key */ 372 /* search all the process keyrings for a key */
284 key = search_process_keyrings_aux(type, description, type->match); 373 key = search_process_keyrings(type, description, type->match, current);
285 374
286 if (PTR_ERR(key) == -EAGAIN) { 375 if (PTR_ERR(key) == -EAGAIN) {
287 /* the search failed, but the keyrings were searchable, so we 376 /* the search failed, but the keyrings were searchable, so we
@@ -292,12 +381,13 @@ struct key *request_key(struct key_type *type,
292 381
293 /* - get hold of the user's construction queue */ 382 /* - get hold of the user's construction queue */
294 user = key_user_lookup(current->fsuid); 383 user = key_user_lookup(current->fsuid);
295 if (!user) { 384 if (!user)
296 key = ERR_PTR(-ENOMEM); 385 goto nomem;
297 goto error; 386
298 } 387 do {
388 if (signal_pending(current))
389 goto interrupted;
299 390
300 for (;;) {
301 /* ask userspace (returns NULL if it waited on a key 391 /* ask userspace (returns NULL if it waited on a key
302 * being constructed) */ 392 * being constructed) */
303 key = request_key_construction(type, description, 393 key = request_key_construction(type, description,
@@ -307,18 +397,46 @@ struct key *request_key(struct key_type *type,
307 397
308 /* someone else made the key we want, so we need to 398 /* someone else made the key we want, so we need to
309 * search again as it might now be available to us */ 399 * search again as it might now be available to us */
310 key = search_process_keyrings_aux(type, description, 400 key = search_process_keyrings(type, description,
311 type->match); 401 type->match, current);
312 if (PTR_ERR(key) != -EAGAIN) 402
313 break; 403 } while (PTR_ERR(key) == -EAGAIN);
314 }
315 404
316 key_user_put(user); 405 key_user_put(user);
406
407 /* link the new key into the appropriate keyring */
408 if (!PTR_ERR(key))
409 request_key_link(key, dest_keyring);
317 } 410 }
318 411
319 error: 412error:
413 kleave(" = %p", key);
320 return key; 414 return key;
321 415
416nomem:
417 key = ERR_PTR(-ENOMEM);
418 goto error;
419
420interrupted:
421 key_user_put(user);
422 key = ERR_PTR(-EINTR);
423 goto error;
424
425} /* end request_key_and_link() */
426
427/*****************************************************************************/
428/*
429 * request a key
430 * - search the process's keyrings
431 * - check the list of keys being created or updated
432 * - call out to userspace for a key if supplementary info was provided
433 */
434struct key *request_key(struct key_type *type,
435 const char *description,
436 const char *callout_info)
437{
438 return request_key_and_link(type, description, callout_info, NULL);
439
322} /* end request_key() */ 440} /* end request_key() */
323 441
324EXPORT_SYMBOL(request_key); 442EXPORT_SYMBOL(request_key);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
new file mode 100644
index 000000000000..f22264632229
--- /dev/null
+++ b/security/keys/request_key_auth.c
@@ -0,0 +1,180 @@
1/* request_key_auth.c: request key authorisation controlling key def
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/err.h>
15#include <linux/seq_file.h>
16#include "internal.h"
17
18static int request_key_auth_instantiate(struct key *, const void *, size_t);
19static void request_key_auth_describe(const struct key *, struct seq_file *);
20static void request_key_auth_destroy(struct key *);
21
22/*
23 * the request-key authorisation key type definition
24 */
25struct key_type key_type_request_key_auth = {
26 .name = ".request_key_auth",
27 .def_datalen = sizeof(struct request_key_auth),
28 .instantiate = request_key_auth_instantiate,
29 .describe = request_key_auth_describe,
30 .destroy = request_key_auth_destroy,
31};
32
33/*****************************************************************************/
34/*
35 * instantiate a request-key authorisation record
36 */
37static int request_key_auth_instantiate(struct key *key,
38 const void *data,
39 size_t datalen)
40{
41 struct request_key_auth *rka, *irka;
42 struct key *instkey;
43 int ret;
44
45 ret = -ENOMEM;
46 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
47 if (rka) {
48 /* see if the calling process is already servicing the key
49 * request of another process */
50 instkey = key_get_instantiation_authkey(0);
51 if (!IS_ERR(instkey)) {
52 /* it is - use that instantiation context here too */
53 irka = instkey->payload.data;
54 rka->context = irka->context;
55 rka->pid = irka->pid;
56 key_put(instkey);
57 }
58 else {
59 /* it isn't - use this process as the context */
60 rka->context = current;
61 rka->pid = current->pid;
62 }
63
64 rka->target_key = key_get((struct key *) data);
65 key->payload.data = rka;
66 ret = 0;
67 }
68
69 return ret;
70
71} /* end request_key_auth_instantiate() */
72
73/*****************************************************************************/
74/*
75 *
76 */
77static void request_key_auth_describe(const struct key *key,
78 struct seq_file *m)
79{
80 struct request_key_auth *rka = key->payload.data;
81
82 seq_puts(m, "key:");
83 seq_puts(m, key->description);
84 seq_printf(m, " pid:%d", rka->pid);
85
86} /* end request_key_auth_describe() */
87
88/*****************************************************************************/
89/*
90 * destroy an instantiation authorisation token key
91 */
92static void request_key_auth_destroy(struct key *key)
93{
94 struct request_key_auth *rka = key->payload.data;
95
96 kenter("{%d}", key->serial);
97
98 key_put(rka->target_key);
99
100} /* end request_key_auth_destroy() */
101
102/*****************************************************************************/
103/*
104 * create a session keyring to be for the invokation of /sbin/request-key and
105 * stick an authorisation token in it
106 */
107struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
108{
109 struct key *keyring, *rkakey = NULL;
110 char desc[20];
111 int ret;
112
113 kenter("%d,", target->serial);
114
115 /* allocate a new session keyring */
116 sprintf(desc, "_req.%u", target->serial);
117
118 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
119 if (IS_ERR(keyring)) {
120 kleave("= %ld", PTR_ERR(keyring));
121 return keyring;
122 }
123
124 /* allocate the auth key */
125 sprintf(desc, "%x", target->serial);
126
127 rkakey = key_alloc(&key_type_request_key_auth, desc,
128 current->fsuid, current->fsgid,
129 KEY_USR_VIEW, 1);
130 if (IS_ERR(rkakey)) {
131 key_put(keyring);
132 kleave("= %ld", PTR_ERR(rkakey));
133 return rkakey;
134 }
135
136 /* construct and attach to the keyring */
137 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
138 if (ret < 0) {
139 key_revoke(rkakey);
140 key_put(rkakey);
141 key_put(keyring);
142 kleave("= %d", ret);
143 return ERR_PTR(ret);
144 }
145
146 *_rkakey = rkakey;
147 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
148 return keyring;
149
150} /* end request_key_auth_new() */
151
152/*****************************************************************************/
153/*
154 * get the authorisation key for instantiation of a specific key if attached to
155 * the current process's keyrings
156 * - this key is inserted into a keyring and that is set as /sbin/request-key's
157 * session keyring
158 * - a target_id of zero specifies any valid token
159 */
160struct key *key_get_instantiation_authkey(key_serial_t target_id)
161{
162 struct task_struct *tsk = current;
163 struct key *instkey;
164
165 /* we must have our own personal session keyring */
166 if (!tsk->signal->session_keyring)
167 return ERR_PTR(-EACCES);
168
169 /* and it must contain a suitable request authorisation key
170 * - lock RCU against session keyring changing
171 */
172 rcu_read_lock();
173
174 instkey = keyring_search_instkey(
175 rcu_dereference(tsk->signal->session_keyring), target_id);
176
177 rcu_read_unlock();
178 return instkey;
179
180} /* end key_get_instantiation_authkey() */