]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - security/keys/request_key.c
Update from upstream with manual merge of Yasunori Goto's
[mirror_ubuntu-artful-kernel.git] / security / keys / request_key.c
1 /* request_key.c: request a key from userspace
2 *
3 * Copyright (C) 2004-5 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 * See Documentation/keys-request-key.txt
12 */
13
14 #include <linux/module.h>
15 #include <linux/sched.h>
16 #include <linux/kmod.h>
17 #include <linux/err.h>
18 #include <linux/keyctl.h>
19 #include "internal.h"
20
21 struct key_construction {
22 struct list_head link; /* link in construction queue */
23 struct key *key; /* key being constructed */
24 };
25
26 /* when waiting for someone else's keys, you get added to this */
27 DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
28
29 /*****************************************************************************/
30 /*
31 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
33 */
34 static int call_request_key(struct key *key,
35 const char *op,
36 const char *callout_info)
37 {
38 struct task_struct *tsk = current;
39 key_serial_t prkey, sskey;
40 struct key *session_keyring, *rkakey;
41 char *argv[10], *envp[3], uid_str[12], gid_str[12];
42 char key_str[12], keyring_str[3][12];
43 int ret, i;
44
45 kenter("{%d},%s,%s", key->serial, op, callout_info);
46
47 /* generate a new session keyring with an auth key in it */
48 session_keyring = request_key_auth_new(key, &rkakey);
49 if (IS_ERR(session_keyring)) {
50 ret = PTR_ERR(session_keyring);
51 goto error;
52 }
53
54 /* record the UID and GID */
55 sprintf(uid_str, "%d", current->fsuid);
56 sprintf(gid_str, "%d", current->fsgid);
57
58 /* we say which key is under construction */
59 sprintf(key_str, "%d", key->serial);
60
61 /* we specify the process's default keyrings */
62 sprintf(keyring_str[0], "%d",
63 tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
64
65 prkey = 0;
66 if (tsk->signal->process_keyring)
67 prkey = tsk->signal->process_keyring->serial;
68
69 sprintf(keyring_str[1], "%d", prkey);
70
71 if (tsk->signal->session_keyring) {
72 rcu_read_lock();
73 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
74 rcu_read_unlock();
75 }
76 else {
77 sskey = tsk->user->session_keyring->serial;
78 }
79
80 sprintf(keyring_str[2], "%d", sskey);
81
82 /* set up a minimal environment */
83 i = 0;
84 envp[i++] = "HOME=/";
85 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
86 envp[i] = NULL;
87
88 /* set up the argument list */
89 i = 0;
90 argv[i++] = "/sbin/request-key";
91 argv[i++] = (char *) op;
92 argv[i++] = key_str;
93 argv[i++] = uid_str;
94 argv[i++] = gid_str;
95 argv[i++] = keyring_str[0];
96 argv[i++] = keyring_str[1];
97 argv[i++] = keyring_str[2];
98 argv[i++] = (char *) callout_info;
99 argv[i] = NULL;
100
101 /* do it */
102 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
103
104 /* dispose of the special keys */
105 key_revoke(rkakey);
106 key_put(rkakey);
107 key_put(session_keyring);
108
109 error:
110 kleave(" = %d", ret);
111 return ret;
112
113 } /* end call_request_key() */
114
115 /*****************************************************************************/
116 /*
117 * call out to userspace for the key
118 * - called with the construction sem held, but the sem is dropped here
119 * - we ignore program failure and go on key status instead
120 */
121 static struct key *__request_key_construction(struct key_type *type,
122 const char *description,
123 const char *callout_info)
124 {
125 struct key_construction cons;
126 struct timespec now;
127 struct key *key;
128 int ret, negated;
129
130 kenter("%s,%s,%s", type->name, description, callout_info);
131
132 /* create a key and add it to the queue */
133 key = key_alloc(type, description,
134 current->fsuid, current->fsgid, KEY_POS_ALL, 0);
135 if (IS_ERR(key))
136 goto alloc_failed;
137
138 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
139
140 cons.key = key;
141 list_add_tail(&cons.link, &key->user->consq);
142
143 /* we drop the construction sem here on behalf of the caller */
144 up_write(&key_construction_sem);
145
146 /* make the call */
147 ret = call_request_key(key, "create", callout_info);
148 if (ret < 0)
149 goto request_failed;
150
151 /* if the key wasn't instantiated, then we want to give an error */
152 ret = -ENOKEY;
153 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154 goto request_failed;
155
156 down_write(&key_construction_sem);
157 list_del(&cons.link);
158 up_write(&key_construction_sem);
159
160 /* also give an error if the key was negatively instantiated */
161 check_not_negative:
162 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
163 key_put(key);
164 key = ERR_PTR(-ENOKEY);
165 }
166
167 out:
168 kleave(" = %p", key);
169 return key;
170
171 request_failed:
172 /* it wasn't instantiated
173 * - remove from construction queue
174 * - mark the key as dead
175 */
176 negated = 0;
177 down_write(&key_construction_sem);
178
179 list_del(&cons.link);
180
181 /* check it didn't get instantiated between the check and the down */
182 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
183 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
184 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
185 negated = 1;
186 }
187
188 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
189
190 up_write(&key_construction_sem);
191
192 if (!negated)
193 goto check_not_negative; /* surprisingly, the key got
194 * instantiated */
195
196 /* set the timeout and store in the session keyring if we can */
197 now = current_kernel_time();
198 key->expiry = now.tv_sec + key_negative_timeout;
199
200 if (current->signal->session_keyring) {
201 struct key *keyring;
202
203 rcu_read_lock();
204 keyring = rcu_dereference(current->signal->session_keyring);
205 atomic_inc(&keyring->usage);
206 rcu_read_unlock();
207
208 key_link(keyring, key);
209 key_put(keyring);
210 }
211
212 key_put(key);
213
214 /* notify anyone who was waiting */
215 wake_up_all(&request_key_conswq);
216
217 key = ERR_PTR(ret);
218 goto out;
219
220 alloc_failed:
221 up_write(&key_construction_sem);
222 goto out;
223
224 } /* end __request_key_construction() */
225
226 /*****************************************************************************/
227 /*
228 * call out to userspace to request the key
229 * - we check the construction queue first to see if an appropriate key is
230 * already being constructed by userspace
231 */
232 static struct key *request_key_construction(struct key_type *type,
233 const char *description,
234 struct key_user *user,
235 const char *callout_info)
236 {
237 struct key_construction *pcons;
238 struct key *key, *ckey;
239
240 DECLARE_WAITQUEUE(myself, current);
241
242 kenter("%s,%s,{%d},%s",
243 type->name, description, user->uid, callout_info);
244
245 /* see if there's such a key under construction already */
246 down_write(&key_construction_sem);
247
248 list_for_each_entry(pcons, &user->consq, link) {
249 ckey = pcons->key;
250
251 if (ckey->type != type)
252 continue;
253
254 if (type->match(ckey, description))
255 goto found_key_under_construction;
256 }
257
258 /* see about getting userspace to construct the key */
259 key = __request_key_construction(type, description, callout_info);
260 error:
261 kleave(" = %p", key);
262 return key;
263
264 /* someone else has the same key under construction
265 * - we want to keep an eye on their key
266 */
267 found_key_under_construction:
268 atomic_inc(&ckey->usage);
269 up_write(&key_construction_sem);
270
271 /* wait for the key to be completed one way or another */
272 add_wait_queue(&request_key_conswq, &myself);
273
274 for (;;) {
275 set_current_state(TASK_INTERRUPTIBLE);
276 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
277 break;
278 if (signal_pending(current))
279 break;
280 schedule();
281 }
282
283 set_current_state(TASK_RUNNING);
284 remove_wait_queue(&request_key_conswq, &myself);
285
286 /* we'll need to search this process's keyrings to see if the key is
287 * now there since we can't automatically assume it's also available
288 * there */
289 key_put(ckey);
290 ckey = NULL;
291
292 key = NULL; /* request a retry */
293 goto error;
294
295 } /* end request_key_construction() */
296
297 /*****************************************************************************/
298 /*
299 * link a freshly minted key to an appropriate destination keyring
300 */
301 static void request_key_link(struct key *key, struct key *dest_keyring)
302 {
303 struct task_struct *tsk = current;
304 struct key *drop = NULL;
305
306 kenter("{%d},%p", key->serial, dest_keyring);
307
308 /* find the appropriate keyring */
309 if (!dest_keyring) {
310 switch (tsk->jit_keyring) {
311 case KEY_REQKEY_DEFL_DEFAULT:
312 case KEY_REQKEY_DEFL_THREAD_KEYRING:
313 dest_keyring = tsk->thread_keyring;
314 if (dest_keyring)
315 break;
316
317 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
318 dest_keyring = tsk->signal->process_keyring;
319 if (dest_keyring)
320 break;
321
322 case KEY_REQKEY_DEFL_SESSION_KEYRING:
323 rcu_read_lock();
324 dest_keyring = key_get(
325 rcu_dereference(tsk->signal->session_keyring));
326 rcu_read_unlock();
327 drop = dest_keyring;
328
329 if (dest_keyring)
330 break;
331
332 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
333 dest_keyring = current->user->session_keyring;
334 break;
335
336 case KEY_REQKEY_DEFL_USER_KEYRING:
337 dest_keyring = current->user->uid_keyring;
338 break;
339
340 case KEY_REQKEY_DEFL_GROUP_KEYRING:
341 default:
342 BUG();
343 }
344 }
345
346 /* and attach the key to it */
347 key_link(dest_keyring, key);
348
349 key_put(drop);
350
351 kleave("");
352
353 } /* end request_key_link() */
354
355 /*****************************************************************************/
356 /*
357 * request a key
358 * - search the process's keyrings
359 * - check the list of keys being created or updated
360 * - call out to userspace for a key if supplementary info was provided
361 * - cache the key in an appropriate keyring
362 */
363 struct key *request_key_and_link(struct key_type *type,
364 const char *description,
365 const char *callout_info,
366 struct key *dest_keyring)
367 {
368 struct key_user *user;
369 struct key *key;
370 key_ref_t key_ref;
371
372 kenter("%s,%s,%s,%p",
373 type->name, description, callout_info, dest_keyring);
374
375 /* search all the process keyrings for a key */
376 key_ref = search_process_keyrings(type, description, type->match,
377 current);
378
379 kdebug("search 1: %p", key_ref);
380
381 if (!IS_ERR(key_ref)) {
382 key = key_ref_to_ptr(key_ref);
383 }
384 else if (PTR_ERR(key_ref) != -EAGAIN) {
385 key = ERR_PTR(PTR_ERR(key_ref));
386 }
387 else {
388 /* the search failed, but the keyrings were searchable, so we
389 * should consult userspace if we can */
390 key = ERR_PTR(-ENOKEY);
391 if (!callout_info)
392 goto error;
393
394 /* - get hold of the user's construction queue */
395 user = key_user_lookup(current->fsuid);
396 if (!user)
397 goto nomem;
398
399 for (;;) {
400 if (signal_pending(current))
401 goto interrupted;
402
403 /* ask userspace (returns NULL if it waited on a key
404 * being constructed) */
405 key = request_key_construction(type, description,
406 user, callout_info);
407 if (key)
408 break;
409
410 /* someone else made the key we want, so we need to
411 * search again as it might now be available to us */
412 key_ref = search_process_keyrings(type, description,
413 type->match,
414 current);
415
416 kdebug("search 2: %p", key_ref);
417
418 if (!IS_ERR(key_ref)) {
419 key = key_ref_to_ptr(key_ref);
420 break;
421 }
422
423 if (PTR_ERR(key_ref) != -EAGAIN) {
424 key = ERR_PTR(PTR_ERR(key_ref));
425 break;
426 }
427 }
428
429 key_user_put(user);
430
431 /* link the new key into the appropriate keyring */
432 if (!IS_ERR(key))
433 request_key_link(key, dest_keyring);
434 }
435
436 error:
437 kleave(" = %p", key);
438 return key;
439
440 nomem:
441 key = ERR_PTR(-ENOMEM);
442 goto error;
443
444 interrupted:
445 key_user_put(user);
446 key = ERR_PTR(-EINTR);
447 goto error;
448
449 } /* end request_key_and_link() */
450
451 /*****************************************************************************/
452 /*
453 * request a key
454 * - search the process's keyrings
455 * - check the list of keys being created or updated
456 * - call out to userspace for a key if supplementary info was provided
457 */
458 struct key *request_key(struct key_type *type,
459 const char *description,
460 const char *callout_info)
461 {
462 return request_key_and_link(type, description, callout_info, NULL);
463
464 } /* end request_key() */
465
466 EXPORT_SYMBOL(request_key);
467
468 /*****************************************************************************/
469 /*
470 * validate a key
471 */
472 int key_validate(struct key *key)
473 {
474 struct timespec now;
475 int ret = 0;
476
477 if (key) {
478 /* check it's still accessible */
479 ret = -EKEYREVOKED;
480 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
481 test_bit(KEY_FLAG_DEAD, &key->flags))
482 goto error;
483
484 /* check it hasn't expired */
485 ret = 0;
486 if (key->expiry) {
487 now = current_kernel_time();
488 if (now.tv_sec >= key->expiry)
489 ret = -EKEYEXPIRED;
490 }
491 }
492
493 error:
494 return ret;
495
496 } /* end key_validate() */
497
498 EXPORT_SYMBOL(key_validate);