aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2005-06-24 01:00:56 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:05:19 -0400
commit3e30148c3d524a9c1c63ca28261bc24c457eb07a (patch)
treea2fcc46cc11fe871ad976c07476d934a07313576
parent8589b4e00e352f983259140f25a262d973be6bc5 (diff)
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes: (1) There's a new special key type called ".request_key_auth". This is an authorisation key for when one process requests a key and another process is started to construct it. This type of key cannot be created by the user; nor can it be requested by kernel services. Authorisation keys hold two references: (a) Each refers to a key being constructed. When the key being constructed is instantiated the authorisation key is revoked, rendering it of no further use. (b) The "authorising process". This is either: (i) the process that called request_key(), or: (ii) if the process that called request_key() itself had an authorisation key in its session keyring, then the authorising process referred to by that authorisation key will also be referred to by the new authorisation key. This means that the process that initiated a chain of key requests will authorise the lot of them, and will, by default, wind up with the keys obtained from them in its keyrings. (2) request_key() creates an authorisation key which is then passed to /sbin/request-key in as part of a new session keyring. (3) When request_key() is searching for a key to hand back to the caller, if it comes across an authorisation key in the session keyring of the calling process, it will also search the keyrings of the process specified therein and it will use the specified process's credentials (fsuid, fsgid, groups) to do that rather than the calling process's credentials. This allows a process started by /sbin/request-key to find keys belonging to the authorising process. (4) A key can be read, even if the process executing KEYCTL_READ doesn't have direct read or search permission if that key is contained within the keyrings of a process specified by an authorisation key found within the calling process's session keyring, and is searchable using the credentials of the authorising process. This allows a process started by /sbin/request-key to read keys belonging to the authorising process. (5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or KEYCTL_NEGATE will specify a keyring of the authorising process, rather than the process doing the instantiation. (6) One of the process keyrings can be nominated as the default to which request_key() should attach new keys if not otherwise specified. This is done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_* constants. The current setting can also be read using this call. (7) request_key() is partially interruptible. If it is waiting for another process to finish constructing a key, it can be interrupted. This permits a request-key cycle to be broken without recourse to rebooting. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/keys.txt34
-rw-r--r--include/linux/key-ui.h41
-rw-r--r--include/linux/key.h9
-rw-r--r--include/linux/keyctl.h11
-rw-r--r--include/linux/sched.h8
-rw-r--r--kernel/sys.c2
-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
15 files changed, 779 insertions, 191 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 3df40c1fe15a..0321ded4b9ae 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -591,6 +591,37 @@ The keyctl syscall functions are:
591 this case too. 591 this case too.
592 592
593 593
594 (*) Set the default request-key destination keyring.
595
596 long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
597
598 This sets the default keyring to which implicitly requested keys will be
599 attached for this thread. reqkey_defl should be one of these constants:
600
601 CONSTANT VALUE NEW DEFAULT KEYRING
602 ====================================== ====== =======================
603 KEY_REQKEY_DEFL_NO_CHANGE -1 No change
604 KEY_REQKEY_DEFL_DEFAULT 0 Default[1]
605 KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring
606 KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring
607 KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring
608 KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring
609 KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring
610 KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring
611
612 The old default will be returned if successful and error EINVAL will be
613 returned if reqkey_defl is not one of the above values.
614
615 The default keyring can be overridden by the keyring indicated to the
616 request_key() system call.
617
618 Note that this setting is inherited across fork/exec.
619
620 [1] The default default is: the thread keyring if there is one, otherwise
621 the process keyring if there is one, otherwise the session keyring if
622 there is one, otherwise the user default session keyring.
623
624
594=============== 625===============
595KERNEL SERVICES 626KERNEL SERVICES
596=============== 627===============
@@ -626,6 +657,9 @@ payload contents" for more information.
626 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be 657 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
627 returned. 658 returned.
628 659
660 If successful, the key will have been attached to the default keyring for
661 implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
662
629 663
630(*) When it is no longer required, the key should be released using: 664(*) When it is no longer required, the key should be released using:
631 665
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index 159ca8d54e9a..cc326174a808 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -1,4 +1,4 @@
1/* key-ui.h: key userspace interface stuff for use by keyfs 1/* key-ui.h: key userspace interface stuff
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -84,8 +84,45 @@ static inline int key_any_permission(const struct key *key, key_perm_t perm)
84 return kperm != 0; 84 return kperm != 0;
85} 85}
86 86
87static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid)
88{
89 int ret;
90
91 task_lock(tsk);
92 ret = groups_search(tsk->group_info, gid);
93 task_unlock(tsk);
94 return ret;
95}
96
97static inline int key_task_permission(const struct key *key,
98 struct task_struct *context,
99 key_perm_t perm)
100{
101 key_perm_t kperm;
102
103 if (key->uid == context->fsuid) {
104 kperm = key->perm >> 16;
105 }
106 else if (key->gid != -1 &&
107 key->perm & KEY_GRP_ALL && (
108 key->gid == context->fsgid ||
109 key_task_groups_search(context, key->gid)
110 )
111 ) {
112 kperm = key->perm >> 8;
113 }
114 else {
115 kperm = key->perm;
116 }
117
118 kperm = kperm & perm & KEY_ALL;
119
120 return kperm == perm;
121
122}
87 123
88extern struct key *lookup_user_key(key_serial_t id, int create, int part, 124extern struct key *lookup_user_key(struct task_struct *context,
125 key_serial_t id, int create, int partial,
89 key_perm_t perm); 126 key_perm_t perm);
90 127
91extern long join_session_keyring(const char *name); 128extern long join_session_keyring(const char *name);
diff --git a/include/linux/key.h b/include/linux/key.h
index 2bfbf88d2740..970bbd916cf4 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -199,10 +199,12 @@ extern int key_payload_reserve(struct key *key, size_t datalen);
199extern int key_instantiate_and_link(struct key *key, 199extern int key_instantiate_and_link(struct key *key,
200 const void *data, 200 const void *data,
201 size_t datalen, 201 size_t datalen,
202 struct key *keyring); 202 struct key *keyring,
203 struct key *instkey);
203extern int key_negate_and_link(struct key *key, 204extern int key_negate_and_link(struct key *key,
204 unsigned timeout, 205 unsigned timeout,
205 struct key *keyring); 206 struct key *keyring,
207 struct key *instkey);
206extern void key_revoke(struct key *key); 208extern void key_revoke(struct key *key);
207extern void key_put(struct key *key); 209extern void key_put(struct key *key);
208 210
@@ -245,9 +247,6 @@ extern struct key *keyring_search(struct key *keyring,
245 struct key_type *type, 247 struct key_type *type,
246 const char *description); 248 const char *description);
247 249
248extern struct key *search_process_keyrings(struct key_type *type,
249 const char *description);
250
251extern int keyring_add_key(struct key *keyring, 250extern int keyring_add_key(struct key *keyring,
252 struct key *key); 251 struct key *key);
253 252
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 381dedc370a3..8d7c59a29e09 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -20,6 +20,16 @@
20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ 20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ 21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
22 22
23/* request-key default keyrings */
24#define KEY_REQKEY_DEFL_NO_CHANGE -1
25#define KEY_REQKEY_DEFL_DEFAULT 0
26#define KEY_REQKEY_DEFL_THREAD_KEYRING 1
27#define KEY_REQKEY_DEFL_PROCESS_KEYRING 2
28#define KEY_REQKEY_DEFL_SESSION_KEYRING 3
29#define KEY_REQKEY_DEFL_USER_KEYRING 4
30#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
31#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
32
23/* keyctl commands */ 33/* keyctl commands */
24#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ 34#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
25#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */ 35#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */
@@ -35,5 +45,6 @@
35#define KEYCTL_READ 11 /* read a key or keyring's contents */ 45#define KEYCTL_READ 11 /* read a key or keyring's contents */
36#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ 46#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
37#define KEYCTL_NEGATE 13 /* negate a partially constructed key */ 47#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
48#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
38 49
39#endif /* _LINUX_KEYCTL_H */ 50#endif /* _LINUX_KEYCTL_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 901742f92389..2c69682b0444 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -561,9 +561,10 @@ struct group_info {
561 groups_free(group_info); \ 561 groups_free(group_info); \
562} while (0) 562} while (0)
563 563
564struct group_info *groups_alloc(int gidsetsize); 564extern struct group_info *groups_alloc(int gidsetsize);
565void groups_free(struct group_info *group_info); 565extern void groups_free(struct group_info *group_info);
566int set_current_groups(struct group_info *group_info); 566extern int set_current_groups(struct group_info *group_info);
567extern int groups_search(struct group_info *group_info, gid_t grp);
567/* access the groups "array" with this macro */ 568/* access the groups "array" with this macro */
568#define GROUP_AT(gi, i) \ 569#define GROUP_AT(gi, i) \
569 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) 570 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
@@ -660,6 +661,7 @@ struct task_struct {
660 struct user_struct *user; 661 struct user_struct *user;
661#ifdef CONFIG_KEYS 662#ifdef CONFIG_KEYS
662 struct key *thread_keyring; /* keyring private to this thread */ 663 struct key *thread_keyring; /* keyring private to this thread */
664 unsigned char jit_keyring; /* default keyring to attach requested keys to */
663#endif 665#endif
664 int oomkilladj; /* OOM kill score adjustment (bit shift). */ 666 int oomkilladj; /* OOM kill score adjustment (bit shift). */
665 char comm[TASK_COMM_LEN]; /* executable name excluding path 667 char comm[TASK_COMM_LEN]; /* executable name excluding path
diff --git a/kernel/sys.c b/kernel/sys.c
index 5a9d6b075016..da24bc1292db 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1259,7 +1259,7 @@ static void groups_sort(struct group_info *group_info)
1259} 1259}
1260 1260
1261/* a simple bsearch */ 1261/* a simple bsearch */
1262static int groups_search(struct group_info *group_info, gid_t grp) 1262int groups_search(struct group_info *group_info, gid_t grp)
1263{ 1263{
1264 int left, right; 1264 int left, right;
1265 1265
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() */