aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-10-17 02:29:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:42:57 -0400
commit76181c134f87479fa13bf2548ddf2999055d34d4 (patch)
tree34694341c190e7ecdd3111ee48e4b98602ff012f
parent398c95bdf2c24d7866692a40ba04425aef238cdd (diff)
KEYS: Make request_key() and co fundamentally asynchronous
Make request_key() and co fundamentally asynchronous to make it easier for NFS to make use of them. There are now accessor functions that do asynchronous constructions, a wait function to wait for construction to complete, and a completion function for the key type to indicate completion of construction. Note that the construction queue is now gone. Instead, keys under construction are linked in to the appropriate keyring in advance, and that anyone encountering one must wait for it to be complete before they can use it. This is done automatically for userspace. The following auxiliary changes are also made: (1) Key type implementation stuff is split from linux/key.h into linux/key-type.h. (2) AF_RXRPC provides a way to allocate null rxrpc-type keys so that AFS does not need to call key_instantiate_and_link() directly. (3) Adjust the debugging macros so that they're -Wformat checked even if they are disabled, and make it so they can be enabled simply by defining __KDEBUG to be consistent with other code of mine. (3) Documentation. [alan@lxorguk.ukuu.org.uk: keys: missing word in documentation] Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/keys-request-key.txt25
-rw-r--r--Documentation/keys.txt93
-rw-r--r--Documentation/networking/rxrpc.txt7
-rw-r--r--fs/afs/cell.c17
-rw-r--r--include/keys/rxrpc-type.h2
-rw-r--r--include/linux/key-type.h112
-rw-r--r--include/linux/key.h99
-rw-r--r--net/rxrpc/af_rxrpc.c1
-rw-r--r--net/rxrpc/ar-key.c32
-rw-r--r--security/keys/internal.h35
-rw-r--r--security/keys/key.c34
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/request_key.c556
-rw-r--r--security/keys/request_key_auth.c11
14 files changed, 605 insertions, 435 deletions
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
index c1f64fdf84cb..266955d23ee6 100644
--- a/Documentation/keys-request-key.txt
+++ b/Documentation/keys-request-key.txt
@@ -20,6 +20,19 @@ or:
20 const char *callout_string, 20 const char *callout_string,
21 void *aux); 21 void *aux);
22 22
23or:
24
25 struct key *request_key_async(const struct key_type *type,
26 const char *description,
27 const char *callout_string);
28
29or:
30
31 struct key *request_key_async_with_auxdata(const struct key_type *type,
32 const char *description,
33 const char *callout_string,
34 void *aux);
35
23Or by userspace invoking the request_key system call: 36Or by userspace invoking the request_key system call:
24 37
25 key_serial_t request_key(const char *type, 38 key_serial_t request_key(const char *type,
@@ -32,10 +45,14 @@ does not need to link the key to a keyring to prevent it from being immediately
32destroyed. The kernel interface returns a pointer directly to the key, and 45destroyed. The kernel interface returns a pointer directly to the key, and
33it's up to the caller to destroy the key. 46it's up to the caller to destroy the key.
34 47
35The request_key_with_auxdata() call is like the in-kernel request_key() call, 48The request_key*_with_auxdata() calls are like the in-kernel request_key*()
36except that it permits auxiliary data to be passed to the upcaller (the default 49calls, except that they permit auxiliary data to be passed to the upcaller (the
37is NULL). This is only useful for those key types that define their own upcall 50default is NULL). This is only useful for those key types that define their
38mechanism rather than using /sbin/request-key. 51own upcall mechanism rather than using /sbin/request-key.
52
53The two async in-kernel calls may return keys that are still in the process of
54being constructed. The two non-async ones will wait for construction to
55complete first.
39 56
40The userspace interface links the key to a keyring associated with the process 57The userspace interface links the key to a keyring associated with the process
41to prevent the key from going away, and returns the serial number of the key to 58to prevent the key from going away, and returns the serial number of the key to
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 947d57d53453..51652d39e61c 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -4,7 +4,7 @@
4 4
5This service allows cryptographic keys, authentication tokens, cross-domain 5This service allows cryptographic keys, authentication tokens, cross-domain
6user mappings, and similar to be cached in the kernel for the use of 6user mappings, and similar to be cached in the kernel for the use of
7filesystems other kernel services. 7filesystems and other kernel services.
8 8
9Keyrings are permitted; these are a special type of key that can hold links to 9Keyrings are permitted; these are a special type of key that can hold links to
10other keys. Processes each have three standard keyring subscriptions that a 10other keys. Processes each have three standard keyring subscriptions that a
@@ -726,6 +726,15 @@ call, and the key released upon close. How to deal with conflicting keys due to
726two different users opening the same file is left to the filesystem author to 726two different users opening the same file is left to the filesystem author to
727solve. 727solve.
728 728
729To access the key manager, the following header must be #included:
730
731 <linux/key.h>
732
733Specific key types should have a header file under include/keys/ that should be
734used to access that type. For keys of type "user", for example, that would be:
735
736 <keys/user-type.h>
737
729Note that there are two different types of pointers to keys that may be 738Note that there are two different types of pointers to keys that may be
730encountered: 739encountered:
731 740
@@ -791,6 +800,36 @@ payload contents" for more information.
791 passed to the key_type->request_key() op if it exists. 800 passed to the key_type->request_key() op if it exists.
792 801
793 802
803(*) A key can be requested asynchronously by calling one of:
804
805 struct key *request_key_async(const struct key_type *type,
806 const char *description,
807 const char *callout_string);
808
809 or:
810
811 struct key *request_key_async_with_auxdata(const struct key_type *type,
812 const char *description,
813 const char *callout_string,
814 void *aux);
815
816 which are asynchronous equivalents of request_key() and
817 request_key_with_auxdata() respectively.
818
819 These two functions return with the key potentially still under
820 construction. To wait for contruction completion, the following should be
821 called:
822
823 int wait_for_key_construction(struct key *key, bool intr);
824
825 The function will wait for the key to finish being constructed and then
826 invokes key_validate() to return an appropriate value to indicate the state
827 of the key (0 indicates the key is usable).
828
829 If intr is true, then the wait can be interrupted by a signal, in which
830 case error ERESTARTSYS will be returned.
831
832
794(*) When it is no longer required, the key should be released using: 833(*) When it is no longer required, the key should be released using:
795 834
796 void key_put(struct key *key); 835 void key_put(struct key *key);
@@ -924,7 +963,11 @@ DEFINING A KEY TYPE
924 963
925A kernel service may want to define its own key type. For instance, an AFS 964A kernel service may want to define its own key type. For instance, an AFS
926filesystem might want to define a Kerberos 5 ticket key type. To do this, it 965filesystem might want to define a Kerberos 5 ticket key type. To do this, it
927author fills in a struct key_type and registers it with the system. 966author fills in a key_type struct and registers it with the system.
967
968Source files that implement key types should include the following header file:
969
970 <linux/key-type.h>
928 971
929The structure has a number of fields, some of which are mandatory: 972The structure has a number of fields, some of which are mandatory:
930 973
@@ -1053,22 +1096,44 @@ The structure has a number of fields, some of which are mandatory:
1053 as might happen when the userspace buffer is accessed. 1096 as might happen when the userspace buffer is accessed.
1054 1097
1055 1098
1056 (*) int (*request_key)(struct key *key, struct key *authkey, const char *op, 1099 (*) int (*request_key)(struct key_construction *cons, const char *op,
1057 void *aux); 1100 void *aux);
1058 1101
1059 This method is optional. If provided, request_key() and 1102 This method is optional. If provided, request_key() and friends will
1060 request_key_with_auxdata() will invoke this function rather than 1103 invoke this function rather than upcalling to /sbin/request-key to operate
1061 upcalling to /sbin/request-key to operate upon a key of this type. 1104 upon a key of this type.
1105
1106 The aux parameter is as passed to request_key_async_with_auxdata() and
1107 similar or is NULL otherwise. Also passed are the construction record for
1108 the key to be operated upon and the operation type (currently only
1109 "create").
1110
1111 This method is permitted to return before the upcall is complete, but the
1112 following function must be called under all circumstances to complete the
1113 instantiation process, whether or not it succeeds, whether or not there's
1114 an error:
1115
1116 void complete_request_key(struct key_construction *cons, int error);
1117
1118 The error parameter should be 0 on success, -ve on error. The
1119 construction record is destroyed by this action and the authorisation key
1120 will be revoked. If an error is indicated, the key under construction
1121 will be negatively instantiated if it wasn't already instantiated.
1122
1123 If this method returns an error, that error will be returned to the
1124 caller of request_key*(). complete_request_key() must be called prior to
1125 returning.
1126
1127 The key under construction and the authorisation key can be found in the
1128 key_construction struct pointed to by cons:
1129
1130 (*) struct key *key;
1131
1132 The key under construction.
1062 1133
1063 The aux parameter is as passed to request_key_with_auxdata() or is NULL 1134 (*) struct key *authkey;
1064 otherwise. Also passed are the key to be operated upon, the
1065 authorisation key for this operation and the operation type (currently
1066 only "create").
1067 1135
1068 This function should return only when the upcall is complete. Upon return 1136 The authorisation key.
1069 the authorisation key will be revoked, and the target key will be
1070 negatively instantiated if it is still uninstantiated. The error will be
1071 returned to the caller of request_key*().
1072 1137
1073 1138
1074============================ 1139============================
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index cae231b1c134..c36b64b0020f 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -857,3 +857,10 @@ The kernel interface functions are as follows:
857 857
858 This is used to extract the error number from a message indicating either 858 This is used to extract the error number from a message indicating either
859 a local error occurred or a network error occurred. 859 a local error occurred or a network error occurred.
860
861 (*) Allocate a null key for doing anonymous security.
862
863 struct key *rxrpc_get_null_key(const char *keyname);
864
865 This is used to allocate a null RxRPC key that can be used to indicate
866 anonymous security for a particular domain.
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index ccfa89f35259..970d38f30565 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -33,6 +33,7 @@ static struct afs_cell *afs_cell_root;
33static struct afs_cell *afs_cell_alloc(const char *name, char *vllist) 33static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
34{ 34{
35 struct afs_cell *cell; 35 struct afs_cell *cell;
36 struct key *key;
36 size_t namelen; 37 size_t namelen;
37 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next; 38 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
38 int ret; 39 int ret;
@@ -89,20 +90,14 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
89 do { 90 do {
90 *dp++ = toupper(*cp); 91 *dp++ = toupper(*cp);
91 } while (*cp++); 92 } while (*cp++);
92 cell->anonymous_key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
93 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
94 if (IS_ERR(cell->anonymous_key)) {
95 _debug("no key");
96 ret = PTR_ERR(cell->anonymous_key);
97 goto error;
98 }
99 93
100 ret = key_instantiate_and_link(cell->anonymous_key, NULL, 0, 94 key = rxrpc_get_null_key(keyname);
101 NULL, NULL); 95 if (IS_ERR(key)) {
102 if (ret < 0) { 96 _debug("no key");
103 _debug("instantiate failed"); 97 ret = PTR_ERR(key);
104 goto error; 98 goto error;
105 } 99 }
100 cell->anonymous_key = key;
106 101
107 _debug("anon key %p{%x}", 102 _debug("anon key %p{%x}",
108 cell->anonymous_key, key_serial(cell->anonymous_key)); 103 cell->anonymous_key, key_serial(cell->anonymous_key));
diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h
index e2ee73aef0ee..4ea429b18750 100644
--- a/include/keys/rxrpc-type.h
+++ b/include/keys/rxrpc-type.h
@@ -19,4 +19,6 @@
19 */ 19 */
20extern struct key_type key_type_rxrpc; 20extern struct key_type key_type_rxrpc;
21 21
22extern struct key *rxrpc_get_null_key(const char *);
23
22#endif /* _KEYS_USER_TYPE_H */ 24#endif /* _KEYS_USER_TYPE_H */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
new file mode 100644
index 000000000000..65833d4d5998
--- /dev/null
+++ b/include/linux/key-type.h
@@ -0,0 +1,112 @@
1/* Definitions for key type implementations
2 *
3 * Copyright (C) 2007 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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _LINUX_KEY_TYPE_H
13#define _LINUX_KEY_TYPE_H
14
15#include <linux/key.h>
16
17#ifdef CONFIG_KEYS
18
19/*
20 * key under-construction record
21 * - passed to the request_key actor if supplied
22 */
23struct key_construction {
24 struct key *key; /* key being constructed */
25 struct key *authkey;/* authorisation for key being constructed */
26};
27
28typedef int (*request_key_actor_t)(struct key_construction *key,
29 const char *op, void *aux);
30
31/*
32 * kernel managed key type definition
33 */
34struct key_type {
35 /* name of the type */
36 const char *name;
37
38 /* default payload length for quota precalculation (optional)
39 * - this can be used instead of calling key_payload_reserve(), that
40 * function only needs to be called if the real datalen is different
41 */
42 size_t def_datalen;
43
44 /* instantiate a key of this type
45 * - this method should call key_payload_reserve() to determine if the
46 * user's quota will hold the payload
47 */
48 int (*instantiate)(struct key *key, const void *data, size_t datalen);
49
50 /* update a key of this type (optional)
51 * - this method should call key_payload_reserve() to recalculate the
52 * quota consumption
53 * - the key must be locked against read when modifying
54 */
55 int (*update)(struct key *key, const void *data, size_t datalen);
56
57 /* match a key against a description */
58 int (*match)(const struct key *key, const void *desc);
59
60 /* clear some of the data from a key on revokation (optional)
61 * - the key's semaphore will be write-locked by the caller
62 */
63 void (*revoke)(struct key *key);
64
65 /* clear the data from a key (optional) */
66 void (*destroy)(struct key *key);
67
68 /* describe a key */
69 void (*describe)(const struct key *key, struct seq_file *p);
70
71 /* read a key's data (optional)
72 * - permission checks will be done by the caller
73 * - the key's semaphore will be readlocked by the caller
74 * - should return the amount of data that could be read, no matter how
75 * much is copied into the buffer
76 * - shouldn't do the copy if the buffer is NULL
77 */
78 long (*read)(const struct key *key, char __user *buffer, size_t buflen);
79
80 /* handle request_key() for this type instead of invoking
81 * /sbin/request-key (optional)
82 * - key is the key to instantiate
83 * - authkey is the authority to assume when instantiating this key
84 * - op is the operation to be done, usually "create"
85 * - the call must not return until the instantiation process has run
86 * its course
87 */
88 request_key_actor_t request_key;
89
90 /* internal fields */
91 struct list_head link; /* link in types list */
92};
93
94extern struct key_type key_type_keyring;
95
96extern int register_key_type(struct key_type *ktype);
97extern void unregister_key_type(struct key_type *ktype);
98
99extern int key_payload_reserve(struct key *key, size_t datalen);
100extern int key_instantiate_and_link(struct key *key,
101 const void *data,
102 size_t datalen,
103 struct key *keyring,
104 struct key *instkey);
105extern int key_negate_and_link(struct key *key,
106 unsigned timeout,
107 struct key *keyring,
108 struct key *instkey);
109extern void complete_request_key(struct key_construction *cons, int error);
110
111#endif /* CONFIG_KEYS */
112#endif /* _LINUX_KEY_TYPE_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index a9220e75782e..fcdbd5ed227b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -1,6 +1,6 @@
1/* key.h: authentication token and access key management 1/* Authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004, 2007 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
@@ -175,78 +175,6 @@ struct key {
175 } payload; 175 } payload;
176}; 176};
177 177
178/*****************************************************************************/
179/*
180 * kernel managed key type definition
181 */
182typedef int (*request_key_actor_t)(struct key *key, struct key *authkey,
183 const char *op, void *aux);
184
185struct key_type {
186 /* name of the type */
187 const char *name;
188
189 /* default payload length for quota precalculation (optional)
190 * - this can be used instead of calling key_payload_reserve(), that
191 * function only needs to be called if the real datalen is different
192 */
193 size_t def_datalen;
194
195 /* instantiate a key of this type
196 * - this method should call key_payload_reserve() to determine if the
197 * user's quota will hold the payload
198 */
199 int (*instantiate)(struct key *key, const void *data, size_t datalen);
200
201 /* update a key of this type (optional)
202 * - this method should call key_payload_reserve() to recalculate the
203 * quota consumption
204 * - the key must be locked against read when modifying
205 */
206 int (*update)(struct key *key, const void *data, size_t datalen);
207
208 /* match a key against a description */
209 int (*match)(const struct key *key, const void *desc);
210
211 /* clear some of the data from a key on revokation (optional)
212 * - the key's semaphore will be write-locked by the caller
213 */
214 void (*revoke)(struct key *key);
215
216 /* clear the data from a key (optional) */
217 void (*destroy)(struct key *key);
218
219 /* describe a key */
220 void (*describe)(const struct key *key, struct seq_file *p);
221
222 /* read a key's data (optional)
223 * - permission checks will be done by the caller
224 * - the key's semaphore will be readlocked by the caller
225 * - should return the amount of data that could be read, no matter how
226 * much is copied into the buffer
227 * - shouldn't do the copy if the buffer is NULL
228 */
229 long (*read)(const struct key *key, char __user *buffer, size_t buflen);
230
231 /* handle request_key() for this type instead of invoking
232 * /sbin/request-key (optional)
233 * - key is the key to instantiate
234 * - authkey is the authority to assume when instantiating this key
235 * - op is the operation to be done, usually "create"
236 * - the call must not return until the instantiation process has run
237 * its course
238 */
239 request_key_actor_t request_key;
240
241 /* internal fields */
242 struct list_head link; /* link in types list */
243};
244
245extern struct key_type key_type_keyring;
246
247extern int register_key_type(struct key_type *ktype);
248extern void unregister_key_type(struct key_type *ktype);
249
250extern struct key *key_alloc(struct key_type *type, 178extern struct key *key_alloc(struct key_type *type,
251 const char *desc, 179 const char *desc,
252 uid_t uid, gid_t gid, 180 uid_t uid, gid_t gid,
@@ -259,16 +187,6 @@ extern struct key *key_alloc(struct key_type *type,
259#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ 187#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
260#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 188#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
261 189
262extern int key_payload_reserve(struct key *key, size_t datalen);
263extern int key_instantiate_and_link(struct key *key,
264 const void *data,
265 size_t datalen,
266 struct key *keyring,
267 struct key *instkey);
268extern int key_negate_and_link(struct key *key,
269 unsigned timeout,
270 struct key *keyring,
271 struct key *instkey);
272extern void key_revoke(struct key *key); 190extern void key_revoke(struct key *key);
273extern void key_put(struct key *key); 191extern void key_put(struct key *key);
274 192
@@ -293,6 +211,17 @@ extern struct key *request_key_with_auxdata(struct key_type *type,
293 const char *callout_info, 211 const char *callout_info,
294 void *aux); 212 void *aux);
295 213
214extern struct key *request_key_async(struct key_type *type,
215 const char *description,
216 const char *callout_info);
217
218extern struct key *request_key_async_with_auxdata(struct key_type *type,
219 const char *description,
220 const char *callout_info,
221 void *aux);
222
223extern int wait_for_key_construction(struct key *key, bool intr);
224
296extern int key_validate(struct key *key); 225extern int key_validate(struct key *key);
297 226
298extern key_ref_t key_create_or_update(key_ref_t keyring, 227extern key_ref_t key_create_or_update(key_ref_t keyring,
@@ -328,8 +257,6 @@ extern int keyring_add_key(struct key *keyring,
328 257
329extern struct key *key_lookup(key_serial_t id); 258extern struct key *key_lookup(key_serial_t id);
330 259
331extern void keyring_replace_payload(struct key *key, void *replacement);
332
333#define key_serial(key) ((key) ? (key)->serial : 0) 260#define key_serial(key) ((key) ? (key)->serial : 0)
334 261
335/* 262/*
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 0803f305ed08..c680017f5c8e 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -14,6 +14,7 @@
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/poll.h> 15#include <linux/poll.h>
16#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
17#include <linux/key-type.h>
17#include <net/net_namespace.h> 18#include <net/net_namespace.h>
18#include <net/sock.h> 19#include <net/sock.h>
19#include <net/af_rxrpc.h> 20#include <net/af_rxrpc.h>
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 7e049ff6ae60..9a8ff684da79 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -15,7 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/net.h> 16#include <linux/net.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/key.h> 18#include <linux/key-type.h>
19#include <linux/crypto.h> 19#include <linux/crypto.h>
20#include <net/sock.h> 20#include <net/sock.h>
21#include <net/af_rxrpc.h> 21#include <net/af_rxrpc.h>
@@ -40,7 +40,6 @@ struct key_type key_type_rxrpc = {
40 .destroy = rxrpc_destroy, 40 .destroy = rxrpc_destroy,
41 .describe = rxrpc_describe, 41 .describe = rxrpc_describe,
42}; 42};
43
44EXPORT_SYMBOL(key_type_rxrpc); 43EXPORT_SYMBOL(key_type_rxrpc);
45 44
46/* 45/*
@@ -330,5 +329,32 @@ error:
330 _leave(" = -ENOMEM [ins %d]", ret); 329 _leave(" = -ENOMEM [ins %d]", ret);
331 return -ENOMEM; 330 return -ENOMEM;
332} 331}
333
334EXPORT_SYMBOL(rxrpc_get_server_data_key); 332EXPORT_SYMBOL(rxrpc_get_server_data_key);
333
334/**
335 * rxrpc_get_null_key - Generate a null RxRPC key
336 * @keyname: The name to give the key.
337 *
338 * Generate a null RxRPC key that can be used to indicate anonymous security is
339 * required for a particular domain.
340 */
341struct key *rxrpc_get_null_key(const char *keyname)
342{
343 struct key *key;
344 int ret;
345
346 key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
347 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
348 if (IS_ERR(key))
349 return key;
350
351 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
352 if (ret < 0) {
353 key_revoke(key);
354 key_put(key);
355 return ERR_PTR(ret);
356 }
357
358 return key;
359}
360EXPORT_SYMBOL(rxrpc_get_null_key);
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 1bb416f4bbce..d36d69393356 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-5 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003-5, 2007 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
@@ -12,17 +12,28 @@
12#ifndef _INTERNAL_H 12#ifndef _INTERNAL_H
13#define _INTERNAL_H 13#define _INTERNAL_H
14 14
15#include <linux/key.h> 15#include <linux/key-type.h>
16#include <linux/key-ui.h> 16#include <linux/key-ui.h>
17 17
18#if 0 18static inline __attribute__((format(printf, 1, 2)))
19#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a) 19void no_printk(const char *fmt, ...)
20#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a) 20{
21#define kdebug(FMT, a...) printk(FMT"\n" , ## a) 21}
22
23#ifdef __KDEBUG
24#define kenter(FMT, ...) \
25 printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__)
26#define kleave(FMT, ...) \
27 printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__)
28#define kdebug(FMT, ...) \
29 printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__)
22#else 30#else
23#define kenter(FMT, a...) do {} while(0) 31#define kenter(FMT, ...) \
24#define kleave(FMT, a...) do {} while(0) 32 no_printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__)
25#define kdebug(FMT, a...) do {} while(0) 33#define kleave(FMT, ...) \
34 no_printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__)
35#define kdebug(FMT, ...) \
36 no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__)
26#endif 37#endif
27 38
28extern struct key_type key_type_user; 39extern struct key_type key_type_user;
@@ -36,7 +47,7 @@ extern struct key_type key_type_user;
36 */ 47 */
37struct key_user { 48struct key_user {
38 struct rb_node node; 49 struct rb_node node;
39 struct list_head consq; /* construction queue */ 50 struct mutex cons_lock; /* construction initiation lock */
40 spinlock_t lock; 51 spinlock_t lock;
41 atomic_t usage; /* for accessing qnkeys & qnbytes */ 52 atomic_t usage; /* for accessing qnkeys & qnbytes */
42 atomic_t nkeys; /* number of keys */ 53 atomic_t nkeys; /* number of keys */
@@ -62,7 +73,7 @@ extern void key_user_put(struct key_user *user);
62extern struct rb_root key_serial_tree; 73extern struct rb_root key_serial_tree;
63extern spinlock_t key_serial_lock; 74extern spinlock_t key_serial_lock;
64extern struct semaphore key_alloc_sem; 75extern struct semaphore key_alloc_sem;
65extern struct rw_semaphore key_construction_sem; 76extern struct mutex key_construction_mutex;
66extern wait_queue_head_t request_key_conswq; 77extern wait_queue_head_t request_key_conswq;
67 78
68 79
@@ -109,7 +120,7 @@ extern struct key *request_key_and_link(struct key_type *type,
109struct request_key_auth { 120struct request_key_auth {
110 struct key *target_key; 121 struct key *target_key;
111 struct task_struct *context; 122 struct task_struct *context;
112 const char *callout_info; 123 char *callout_info;
113 pid_t pid; 124 pid_t pid;
114}; 125};
115 126
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bbc6d9d19b..fdd5ca6d89fc 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/* Basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2007 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
@@ -34,7 +34,7 @@ static void key_cleanup(struct work_struct *work);
34static DECLARE_WORK(key_cleanup_task, key_cleanup); 34static DECLARE_WORK(key_cleanup_task, key_cleanup);
35 35
36/* we serialise key instantiation and link */ 36/* we serialise key instantiation and link */
37DECLARE_RWSEM(key_construction_sem); 37DEFINE_MUTEX(key_construction_mutex);
38 38
39/* any key who's type gets unegistered will be re-typed to this */ 39/* any key who's type gets unegistered will be re-typed to this */
40static struct key_type key_type_dead = { 40static struct key_type key_type_dead = {
@@ -104,7 +104,7 @@ struct key_user *key_user_lookup(uid_t uid)
104 candidate->qnkeys = 0; 104 candidate->qnkeys = 0;
105 candidate->qnbytes = 0; 105 candidate->qnbytes = 0;
106 spin_lock_init(&candidate->lock); 106 spin_lock_init(&candidate->lock);
107 INIT_LIST_HEAD(&candidate->consq); 107 mutex_init(&candidate->cons_lock);
108 108
109 rb_link_node(&candidate->node, parent, p); 109 rb_link_node(&candidate->node, parent, p);
110 rb_insert_color(&candidate->node, &key_user_tree); 110 rb_insert_color(&candidate->node, &key_user_tree);
@@ -418,7 +418,7 @@ static int __key_instantiate_and_link(struct key *key,
418 awaken = 0; 418 awaken = 0;
419 ret = -EBUSY; 419 ret = -EBUSY;
420 420
421 down_write(&key_construction_sem); 421 mutex_lock(&key_construction_mutex);
422 422
423 /* can't instantiate twice */ 423 /* can't instantiate twice */
424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -443,11 +443,11 @@ static int __key_instantiate_and_link(struct key *key,
443 } 443 }
444 } 444 }
445 445
446 up_write(&key_construction_sem); 446 mutex_unlock(&key_construction_mutex);
447 447
448 /* wake up anyone waiting for a key to be constructed */ 448 /* wake up anyone waiting for a key to be constructed */
449 if (awaken) 449 if (awaken)
450 wake_up_all(&request_key_conswq); 450 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
451 451
452 return ret; 452 return ret;
453 453
@@ -500,7 +500,7 @@ int key_negate_and_link(struct key *key,
500 if (keyring) 500 if (keyring)
501 down_write(&keyring->sem); 501 down_write(&keyring->sem);
502 502
503 down_write(&key_construction_sem); 503 mutex_lock(&key_construction_mutex);
504 504
505 /* can't instantiate twice */ 505 /* can't instantiate twice */
506 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 506 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -525,14 +525,14 @@ int key_negate_and_link(struct key *key,
525 key_revoke(instkey); 525 key_revoke(instkey);
526 } 526 }
527 527
528 up_write(&key_construction_sem); 528 mutex_unlock(&key_construction_mutex);
529 529
530 if (keyring) 530 if (keyring)
531 up_write(&keyring->sem); 531 up_write(&keyring->sem);
532 532
533 /* wake up anyone waiting for a key to be constructed */ 533 /* wake up anyone waiting for a key to be constructed */
534 if (awaken) 534 if (awaken)
535 wake_up_all(&request_key_conswq); 535 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
536 536
537 return ret; 537 return ret;
538 538
@@ -899,12 +899,14 @@ void key_revoke(struct key *key)
899{ 899{
900 key_check(key); 900 key_check(key);
901 901
902 /* make sure no one's trying to change or use the key when we mark 902 /* make sure no one's trying to change or use the key when we mark it
903 * it */ 903 * - we tell lockdep that we might nest because we might be revoking an
904 down_write(&key->sem); 904 * authorisation key whilst holding the sem on a key we've just
905 set_bit(KEY_FLAG_REVOKED, &key->flags); 905 * instantiated
906 906 */
907 if (key->type->revoke) 907 down_write_nested(&key->sem, 1);
908 if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) &&
909 key->type->revoke)
908 key->type->revoke(key); 910 key->type->revoke(key);
909 911
910 up_write(&key->sem); 912 up_write(&key->sem);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b6f86808475a..2a0eb946fc7e 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -26,7 +26,7 @@ static DEFINE_MUTEX(key_session_mutex);
26/* the root user's tracking struct */ 26/* the root user's tracking struct */
27struct key_user root_key_user = { 27struct key_user root_key_user = {
28 .usage = ATOMIC_INIT(3), 28 .usage = ATOMIC_INIT(3),
29 .consq = LIST_HEAD_INIT(root_key_user.consq), 29 .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock),
30 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), 30 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
31 .nkeys = ATOMIC_INIT(2), 31 .nkeys = ATOMIC_INIT(2),
32 .nikeys = ATOMIC_INIT(2), 32 .nikeys = ATOMIC_INIT(2),
@@ -679,8 +679,18 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
679 break; 679 break;
680 } 680 }
681 681
682 /* check the status */ 682 if (!partial) {
683 if (perm) { 683 ret = wait_for_key_construction(key, true);
684 switch (ret) {
685 case -ERESTARTSYS:
686 goto invalid_key;
687 default:
688 if (perm)
689 goto invalid_key;
690 case 0:
691 break;
692 }
693 } else if (perm) {
684 ret = key_validate(key); 694 ret = key_validate(key);
685 if (ret < 0) 695 if (ret < 0)
686 goto invalid_key; 696 goto invalid_key;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 557500110a13..6381e616c477 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 a key from userspace
2 * 2 *
3 * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2007 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
@@ -18,27 +18,54 @@
18#include <linux/keyctl.h> 18#include <linux/keyctl.h>
19#include "internal.h" 19#include "internal.h"
20 20
21struct key_construction { 21/*
22 struct list_head link; /* link in construction queue */ 22 * wait_on_bit() sleep function for uninterruptible waiting
23 struct key *key; /* key being constructed */ 23 */
24}; 24static int key_wait_bit(void *flags)
25{
26 schedule();
27 return 0;
28}
29
30/*
31 * wait_on_bit() sleep function for interruptible waiting
32 */
33static int key_wait_bit_intr(void *flags)
34{
35 schedule();
36 return signal_pending(current) ? -ERESTARTSYS : 0;
37}
38
39/*
40 * call to complete the construction of a key
41 */
42void complete_request_key(struct key_construction *cons, int error)
43{
44 kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
25 45
26/* when waiting for someone else's keys, you get added to this */ 46 if (error < 0)
27DECLARE_WAIT_QUEUE_HEAD(request_key_conswq); 47 key_negate_and_link(cons->key, key_negative_timeout, NULL,
48 cons->authkey);
49 else
50 key_revoke(cons->authkey);
51
52 key_put(cons->key);
53 key_put(cons->authkey);
54 kfree(cons);
55}
56EXPORT_SYMBOL(complete_request_key);
28 57
29/*****************************************************************************/
30/* 58/*
31 * request userspace finish the construction of a key 59 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" 60 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
33 */ 61 */
34static int call_sbin_request_key(struct key *key, 62static int call_sbin_request_key(struct key_construction *cons,
35 struct key *authkey,
36 const char *op, 63 const char *op,
37 void *aux) 64 void *aux)
38{ 65{
39 struct task_struct *tsk = current; 66 struct task_struct *tsk = current;
40 key_serial_t prkey, sskey; 67 key_serial_t prkey, sskey;
41 struct key *keyring; 68 struct key *key = cons->key, *authkey = cons->authkey, *keyring;
42 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 69 char *argv[9], *envp[3], uid_str[12], gid_str[12];
43 char key_str[12], keyring_str[3][12]; 70 char key_str[12], keyring_str[3][12];
44 char desc[20]; 71 char desc[20];
@@ -82,8 +109,7 @@ static int call_sbin_request_key(struct key *key,
82 rcu_read_lock(); 109 rcu_read_lock();
83 sskey = rcu_dereference(tsk->signal->session_keyring)->serial; 110 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
84 rcu_read_unlock(); 111 rcu_read_unlock();
85 } 112 } else {
86 else {
87 sskey = tsk->user->session_keyring->serial; 113 sskey = tsk->user->session_keyring->serial;
88 } 114 }
89 115
@@ -110,228 +136,77 @@ static int call_sbin_request_key(struct key *key,
110 /* do it */ 136 /* do it */
111 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 137 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
112 UMH_WAIT_PROC); 138 UMH_WAIT_PROC);
139 kdebug("usermode -> 0x%x", ret);
140 if (ret >= 0) {
141 /* ret is the exit/wait code */
142 if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
143 key_validate(key) < 0)
144 ret = -ENOKEY;
145 else
146 /* ignore any errors from userspace if the key was
147 * instantiated */
148 ret = 0;
149 }
113 150
114error_link: 151error_link:
115 key_put(keyring); 152 key_put(keyring);
116 153
117error_alloc: 154error_alloc:
118 kleave(" = %d", ret); 155 kleave(" = %d", ret);
156 complete_request_key(cons, ret);
119 return ret; 157 return ret;
158}
120 159
121} /* end call_sbin_request_key() */
122
123/*****************************************************************************/
124/* 160/*
125 * call out to userspace for the key 161 * call out to userspace for key construction
126 * - called with the construction sem held, but the sem is dropped here
127 * - we ignore program failure and go on key status instead 162 * - we ignore program failure and go on key status instead
128 */ 163 */
129static struct key *__request_key_construction(struct key_type *type, 164static int construct_key(struct key *key, const char *callout_info, void *aux)
130 const char *description,
131 const char *callout_info,
132 void *aux,
133 unsigned long flags)
134{ 165{
166 struct key_construction *cons;
135 request_key_actor_t actor; 167 request_key_actor_t actor;
136 struct key_construction cons; 168 struct key *authkey;
137 struct timespec now; 169 int ret;
138 struct key *key, *authkey;
139 int ret, negated;
140 170
141 kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags); 171 kenter("%d,%s,%p", key->serial, callout_info, aux);
142 172
143 /* create a key and add it to the queue */ 173 cons = kmalloc(sizeof(*cons), GFP_KERNEL);
144 key = key_alloc(type, description, 174 if (!cons)
145 current->fsuid, current->fsgid, current, KEY_POS_ALL, 175 return -ENOMEM;
146 flags);
147 if (IS_ERR(key))
148 goto alloc_failed;
149
150 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
151
152 cons.key = key;
153 list_add_tail(&cons.link, &key->user->consq);
154
155 /* we drop the construction sem here on behalf of the caller */
156 up_write(&key_construction_sem);
157 176
158 /* allocate an authorisation key */ 177 /* allocate an authorisation key */
159 authkey = request_key_auth_new(key, callout_info); 178 authkey = request_key_auth_new(key, callout_info);
160 if (IS_ERR(authkey)) { 179 if (IS_ERR(authkey)) {
180 kfree(cons);
161 ret = PTR_ERR(authkey); 181 ret = PTR_ERR(authkey);
162 authkey = NULL; 182 authkey = NULL;
163 goto alloc_authkey_failed; 183 } else {
164 } 184 cons->authkey = key_get(authkey);
165 185 cons->key = key_get(key);
166 /* make the call */ 186
167 actor = call_sbin_request_key; 187 /* make the call */
168 if (type->request_key) 188 actor = call_sbin_request_key;
169 actor = type->request_key; 189 if (key->type->request_key)
170 ret = actor(key, authkey, "create", aux); 190 actor = key->type->request_key;
171 if (ret < 0) 191
172 goto request_failed; 192 ret = actor(cons, "create", aux);
173 193
174 /* if the key wasn't instantiated, then we want to give an error */ 194 /* check that the actor called complete_request_key() prior to
175 ret = -ENOKEY; 195 * returning an error */
176 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 196 WARN_ON(ret < 0 &&
177 goto request_failed; 197 !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
178 198 key_put(authkey);
179 key_revoke(authkey);
180 key_put(authkey);
181
182 down_write(&key_construction_sem);
183 list_del(&cons.link);
184 up_write(&key_construction_sem);
185
186 /* also give an error if the key was negatively instantiated */
187check_not_negative:
188 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
189 key_put(key);
190 key = ERR_PTR(-ENOKEY);
191 }
192
193out:
194 kleave(" = %p", key);
195 return key;
196
197request_failed:
198 key_revoke(authkey);
199 key_put(authkey);
200
201alloc_authkey_failed:
202 /* it wasn't instantiated
203 * - remove from construction queue
204 * - mark the key as dead
205 */
206 negated = 0;
207 down_write(&key_construction_sem);
208
209 list_del(&cons.link);
210
211 /* check it didn't get instantiated between the check and the down */
212 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
213 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
214 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
215 negated = 1;
216 }
217
218 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
219
220 up_write(&key_construction_sem);
221
222 if (!negated)
223 goto check_not_negative; /* surprisingly, the key got
224 * instantiated */
225
226 /* set the timeout and store in the session keyring if we can */
227 now = current_kernel_time();
228 key->expiry = now.tv_sec + key_negative_timeout;
229
230 if (current->signal->session_keyring) {
231 struct key *keyring;
232
233 rcu_read_lock();
234 keyring = rcu_dereference(current->signal->session_keyring);
235 atomic_inc(&keyring->usage);
236 rcu_read_unlock();
237
238 key_link(keyring, key);
239 key_put(keyring);
240 }
241
242 key_put(key);
243
244 /* notify anyone who was waiting */
245 wake_up_all(&request_key_conswq);
246
247 key = ERR_PTR(ret);
248 goto out;
249
250alloc_failed:
251 up_write(&key_construction_sem);
252 goto out;
253
254} /* end __request_key_construction() */
255
256/*****************************************************************************/
257/*
258 * call out to userspace to request the key
259 * - we check the construction queue first to see if an appropriate key is
260 * already being constructed by userspace
261 */
262static struct key *request_key_construction(struct key_type *type,
263 const char *description,
264 const char *callout_info,
265 void *aux,
266 struct key_user *user,
267 unsigned long flags)
268{
269 struct key_construction *pcons;
270 struct key *key, *ckey;
271
272 DECLARE_WAITQUEUE(myself, current);
273
274 kenter("%s,%s,{%d},%s,%lx",
275 type->name, description, user->uid, callout_info, flags);
276
277 /* see if there's such a key under construction already */
278 down_write(&key_construction_sem);
279
280 list_for_each_entry(pcons, &user->consq, link) {
281 ckey = pcons->key;
282
283 if (ckey->type != type)
284 continue;
285
286 if (type->match(ckey, description))
287 goto found_key_under_construction;
288 } 199 }
289 200
290 /* see about getting userspace to construct the key */ 201 kleave(" = %d", ret);
291 key = __request_key_construction(type, description, callout_info, aux, 202 return ret;
292 flags); 203}
293 error:
294 kleave(" = %p", key);
295 return key;
296
297 /* someone else has the same key under construction
298 * - we want to keep an eye on their key
299 */
300 found_key_under_construction:
301 atomic_inc(&ckey->usage);
302 up_write(&key_construction_sem);
303
304 /* wait for the key to be completed one way or another */
305 add_wait_queue(&request_key_conswq, &myself);
306
307 for (;;) {
308 set_current_state(TASK_INTERRUPTIBLE);
309 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
310 break;
311 if (signal_pending(current))
312 break;
313 schedule();
314 }
315
316 set_current_state(TASK_RUNNING);
317 remove_wait_queue(&request_key_conswq, &myself);
318
319 /* we'll need to search this process's keyrings to see if the key is
320 * now there since we can't automatically assume it's also available
321 * there */
322 key_put(ckey);
323 ckey = NULL;
324
325 key = NULL; /* request a retry */
326 goto error;
327
328} /* end request_key_construction() */
329 204
330/*****************************************************************************/
331/* 205/*
332 * link a freshly minted key to an appropriate destination keyring 206 * link a key to the appropriate destination keyring
207 * - the caller must hold a write lock on the destination keyring
333 */ 208 */
334static void request_key_link(struct key *key, struct key *dest_keyring) 209static void construct_key_make_link(struct key *key, struct key *dest_keyring)
335{ 210{
336 struct task_struct *tsk = current; 211 struct task_struct *tsk = current;
337 struct key *drop = NULL; 212 struct key *drop = NULL;
@@ -363,11 +238,11 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
363 break; 238 break;
364 239
365 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING: 240 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
366 dest_keyring = current->user->session_keyring; 241 dest_keyring = tsk->user->session_keyring;
367 break; 242 break;
368 243
369 case KEY_REQKEY_DEFL_USER_KEYRING: 244 case KEY_REQKEY_DEFL_USER_KEYRING:
370 dest_keyring = current->user->uid_keyring; 245 dest_keyring = tsk->user->uid_keyring;
371 break; 246 break;
372 247
373 case KEY_REQKEY_DEFL_GROUP_KEYRING: 248 case KEY_REQKEY_DEFL_GROUP_KEYRING:
@@ -377,15 +252,115 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
377 } 252 }
378 253
379 /* and attach the key to it */ 254 /* and attach the key to it */
380 key_link(dest_keyring, key); 255 __key_link(dest_keyring, key);
381
382 key_put(drop); 256 key_put(drop);
383
384 kleave(""); 257 kleave("");
258}
385 259
386} /* end request_key_link() */ 260/*
261 * allocate a new key in under-construction state and attempt to link it in to
262 * the requested place
263 * - may return a key that's already under construction instead
264 */
265static int construct_alloc_key(struct key_type *type,
266 const char *description,
267 struct key *dest_keyring,
268 unsigned long flags,
269 struct key_user *user,
270 struct key **_key)
271{
272 struct key *key;
273 key_ref_t key_ref;
274
275 kenter("%s,%s,,,", type->name, description);
276
277 mutex_lock(&user->cons_lock);
278
279 key = key_alloc(type, description,
280 current->fsuid, current->fsgid, current, KEY_POS_ALL,
281 flags);
282 if (IS_ERR(key))
283 goto alloc_failed;
284
285 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
286
287 if (dest_keyring)
288 down_write(&dest_keyring->sem);
289
290 /* attach the key to the destination keyring under lock, but we do need
291 * to do another check just in case someone beat us to it whilst we
292 * waited for locks */
293 mutex_lock(&key_construction_mutex);
294
295 key_ref = search_process_keyrings(type, description, type->match,
296 current);
297 if (!IS_ERR(key_ref))
298 goto key_already_present;
299
300 if (dest_keyring)
301 construct_key_make_link(key, dest_keyring);
302
303 mutex_unlock(&key_construction_mutex);
304 if (dest_keyring)
305 up_write(&dest_keyring->sem);
306 mutex_unlock(&user->cons_lock);
307 *_key = key;
308 kleave(" = 0 [%d]", key_serial(key));
309 return 0;
310
311key_already_present:
312 mutex_unlock(&key_construction_mutex);
313 if (dest_keyring)
314 up_write(&dest_keyring->sem);
315 mutex_unlock(&user->cons_lock);
316 key_put(key);
317 *_key = key = key_ref_to_ptr(key_ref);
318 kleave(" = -EINPROGRESS [%d]", key_serial(key));
319 return -EINPROGRESS;
320
321alloc_failed:
322 mutex_unlock(&user->cons_lock);
323 *_key = NULL;
324 kleave(" = %ld", PTR_ERR(key));
325 return PTR_ERR(key);
326}
327
328/*
329 * commence key construction
330 */
331static struct key *construct_key_and_link(struct key_type *type,
332 const char *description,
333 const char *callout_info,
334 void *aux,
335 struct key *dest_keyring,
336 unsigned long flags)
337{
338 struct key_user *user;
339 struct key *key;
340 int ret;
341
342 user = key_user_lookup(current->fsuid);
343 if (!user)
344 return ERR_PTR(-ENOMEM);
345
346 ret = construct_alloc_key(type, description, dest_keyring, flags, user,
347 &key);
348 key_user_put(user);
349
350 if (ret == 0) {
351 ret = construct_key(key, callout_info, aux);
352 if (ret < 0)
353 goto construction_failed;
354 }
355
356 return key;
357
358construction_failed:
359 key_negate_and_link(key, key_negative_timeout, NULL, NULL);
360 key_put(key);
361 return ERR_PTR(ret);
362}
387 363
388/*****************************************************************************/
389/* 364/*
390 * request a key 365 * request a key
391 * - search the process's keyrings 366 * - search the process's keyrings
@@ -400,7 +375,6 @@ struct key *request_key_and_link(struct key_type *type,
400 struct key *dest_keyring, 375 struct key *dest_keyring,
401 unsigned long flags) 376 unsigned long flags)
402{ 377{
403 struct key_user *user;
404 struct key *key; 378 struct key *key;
405 key_ref_t key_ref; 379 key_ref_t key_ref;
406 380
@@ -412,112 +386,124 @@ struct key *request_key_and_link(struct key_type *type,
412 key_ref = search_process_keyrings(type, description, type->match, 386 key_ref = search_process_keyrings(type, description, type->match,
413 current); 387 current);
414 388
415 kdebug("search 1: %p", key_ref);
416
417 if (!IS_ERR(key_ref)) { 389 if (!IS_ERR(key_ref)) {
418 key = key_ref_to_ptr(key_ref); 390 key = key_ref_to_ptr(key_ref);
419 } 391 } else if (PTR_ERR(key_ref) != -EAGAIN) {
420 else if (PTR_ERR(key_ref) != -EAGAIN) {
421 key = ERR_PTR(PTR_ERR(key_ref)); 392 key = ERR_PTR(PTR_ERR(key_ref));
422 } 393 } else {
423 else {
424 /* the search failed, but the keyrings were searchable, so we 394 /* the search failed, but the keyrings were searchable, so we
425 * should consult userspace if we can */ 395 * should consult userspace if we can */
426 key = ERR_PTR(-ENOKEY); 396 key = ERR_PTR(-ENOKEY);
427 if (!callout_info) 397 if (!callout_info)
428 goto error; 398 goto error;
429 399
430 /* - get hold of the user's construction queue */ 400 key = construct_key_and_link(type, description, callout_info,
431 user = key_user_lookup(current->fsuid); 401 aux, dest_keyring, flags);
432 if (!user)
433 goto nomem;
434
435 for (;;) {
436 if (signal_pending(current))
437 goto interrupted;
438
439 /* ask userspace (returns NULL if it waited on a key
440 * being constructed) */
441 key = request_key_construction(type, description,
442 callout_info, aux,
443 user, flags);
444 if (key)
445 break;
446
447 /* someone else made the key we want, so we need to
448 * search again as it might now be available to us */
449 key_ref = search_process_keyrings(type, description,
450 type->match,
451 current);
452
453 kdebug("search 2: %p", key_ref);
454
455 if (!IS_ERR(key_ref)) {
456 key = key_ref_to_ptr(key_ref);
457 break;
458 }
459
460 if (PTR_ERR(key_ref) != -EAGAIN) {
461 key = ERR_PTR(PTR_ERR(key_ref));
462 break;
463 }
464 }
465
466 key_user_put(user);
467
468 /* link the new key into the appropriate keyring */
469 if (!IS_ERR(key))
470 request_key_link(key, dest_keyring);
471 } 402 }
472 403
473error: 404error:
474 kleave(" = %p", key); 405 kleave(" = %p", key);
475 return key; 406 return key;
407}
476 408
477nomem: 409/*
478 key = ERR_PTR(-ENOMEM); 410 * wait for construction of a key to complete
479 goto error; 411 */
480 412int wait_for_key_construction(struct key *key, bool intr)
481interrupted: 413{
482 key_user_put(user); 414 int ret;
483 key = ERR_PTR(-EINTR);
484 goto error;
485 415
486} /* end request_key_and_link() */ 416 ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
417 intr ? key_wait_bit_intr : key_wait_bit,
418 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
419 if (ret < 0)
420 return ret;
421 return key_validate(key);
422}
423EXPORT_SYMBOL(wait_for_key_construction);
487 424
488/*****************************************************************************/
489/* 425/*
490 * request a key 426 * request a key
491 * - search the process's keyrings 427 * - search the process's keyrings
492 * - check the list of keys being created or updated 428 * - check the list of keys being created or updated
493 * - call out to userspace for a key if supplementary info was provided 429 * - call out to userspace for a key if supplementary info was provided
430 * - waits uninterruptible for creation to complete
494 */ 431 */
495struct key *request_key(struct key_type *type, 432struct key *request_key(struct key_type *type,
496 const char *description, 433 const char *description,
497 const char *callout_info) 434 const char *callout_info)
498{ 435{
499 return request_key_and_link(type, description, callout_info, NULL, 436 struct key *key;
500 NULL, KEY_ALLOC_IN_QUOTA); 437 int ret;
501 438
502} /* end request_key() */ 439 key = request_key_and_link(type, description, callout_info, NULL,
503 440 NULL, KEY_ALLOC_IN_QUOTA);
441 if (!IS_ERR(key)) {
442 ret = wait_for_key_construction(key, false);
443 if (ret < 0) {
444 key_put(key);
445 return ERR_PTR(ret);
446 }
447 }
448 return key;
449}
504EXPORT_SYMBOL(request_key); 450EXPORT_SYMBOL(request_key);
505 451
506/*****************************************************************************/
507/* 452/*
508 * request a key with auxiliary data for the upcaller 453 * request a key with auxiliary data for the upcaller
509 * - search the process's keyrings 454 * - search the process's keyrings
510 * - check the list of keys being created or updated 455 * - check the list of keys being created or updated
511 * - call out to userspace for a key if supplementary info was provided 456 * - call out to userspace for a key if supplementary info was provided
457 * - waits uninterruptible for creation to complete
512 */ 458 */
513struct key *request_key_with_auxdata(struct key_type *type, 459struct key *request_key_with_auxdata(struct key_type *type,
514 const char *description, 460 const char *description,
515 const char *callout_info, 461 const char *callout_info,
516 void *aux) 462 void *aux)
517{ 463{
518 return request_key_and_link(type, description, callout_info, aux, 464 struct key *key;
519 NULL, KEY_ALLOC_IN_QUOTA); 465 int ret;
466
467 key = request_key_and_link(type, description, callout_info, aux,
468 NULL, KEY_ALLOC_IN_QUOTA);
469 if (!IS_ERR(key)) {
470 ret = wait_for_key_construction(key, false);
471 if (ret < 0) {
472 key_put(key);
473 return ERR_PTR(ret);
474 }
475 }
476 return key;
477}
478EXPORT_SYMBOL(request_key_with_auxdata);
520 479
521} /* end request_key_with_auxdata() */ 480/*
481 * request a key (allow async construction)
482 * - search the process's keyrings
483 * - check the list of keys being created or updated
484 * - call out to userspace for a key if supplementary info was provided
485 */
486struct key *request_key_async(struct key_type *type,
487 const char *description,
488 const char *callout_info)
489{
490 return request_key_and_link(type, description, callout_info, NULL,
491 NULL, KEY_ALLOC_IN_QUOTA);
492}
493EXPORT_SYMBOL(request_key_async);
522 494
523EXPORT_SYMBOL(request_key_with_auxdata); 495/*
496 * request a key with auxiliary data for the upcaller (allow async construction)
497 * - search the process's keyrings
498 * - check the list of keys being created or updated
499 * - call out to userspace for a key if supplementary info was provided
500 */
501struct key *request_key_async_with_auxdata(struct key_type *type,
502 const char *description,
503 const char *callout_info,
504 void *aux)
505{
506 return request_key_and_link(type, description, callout_info, aux,
507 NULL, KEY_ALLOC_IN_QUOTA);
508}
509EXPORT_SYMBOL(request_key_async_with_auxdata);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index cbf58a91b00a..510f7be73a2d 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -127,6 +127,7 @@ static void request_key_auth_destroy(struct key *key)
127 } 127 }
128 128
129 key_put(rka->target_key); 129 key_put(rka->target_key);
130 kfree(rka->callout_info);
130 kfree(rka); 131 kfree(rka);
131 132
132} /* end request_key_auth_destroy() */ 133} /* end request_key_auth_destroy() */
@@ -151,6 +152,12 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
151 kleave(" = -ENOMEM"); 152 kleave(" = -ENOMEM");
152 return ERR_PTR(-ENOMEM); 153 return ERR_PTR(-ENOMEM);
153 } 154 }
155 rka->callout_info = kmalloc(strlen(callout_info) + 1, GFP_KERNEL);
156 if (!rka->callout_info) {
157 kleave(" = -ENOMEM");
158 kfree(rka);
159 return ERR_PTR(-ENOMEM);
160 }
154 161
155 /* see if the calling process is already servicing the key request of 162 /* see if the calling process is already servicing the key request of
156 * another process */ 163 * another process */
@@ -179,7 +186,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
179 } 186 }
180 187
181 rka->target_key = key_get(target); 188 rka->target_key = key_get(target);
182 rka->callout_info = callout_info; 189 strcpy(rka->callout_info, callout_info);
183 190
184 /* allocate the auth key */ 191 /* allocate the auth key */
185 sprintf(desc, "%x", target->serial); 192 sprintf(desc, "%x", target->serial);
@@ -203,6 +210,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
203 210
204auth_key_revoked: 211auth_key_revoked:
205 up_read(&current->request_key_auth->sem); 212 up_read(&current->request_key_auth->sem);
213 kfree(rka->callout_info);
206 kfree(rka); 214 kfree(rka);
207 kleave("= -EKEYREVOKED"); 215 kleave("= -EKEYREVOKED");
208 return ERR_PTR(-EKEYREVOKED); 216 return ERR_PTR(-EKEYREVOKED);
@@ -212,6 +220,7 @@ error_inst:
212 key_put(authkey); 220 key_put(authkey);
213error_alloc: 221error_alloc:
214 key_put(rka->target_key); 222 key_put(rka->target_key);
223 kfree(rka->callout_info);
215 kfree(rka); 224 kfree(rka);
216 kleave("= %d", ret); 225 kleave("= %d", ret);
217 return ERR_PTR(ret); 226 return ERR_PTR(ret);