Branch data Line data Source code
1 : : /* Request a key from userspace
2 : : *
3 : : * Copyright (C) 2004-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 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/security/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 <linux/slab.h>
20 : : #include "internal.h"
21 : :
22 : : #define key_negative_timeout 60 /* default timeout on a negative key's existence */
23 : :
24 : : /*
25 : : * wait_on_bit() sleep function for uninterruptible waiting
26 : : */
27 : 0 : static int key_wait_bit(void *flags)
28 : : {
29 : 0 : schedule();
30 : 0 : return 0;
31 : : }
32 : :
33 : : /*
34 : : * wait_on_bit() sleep function for interruptible waiting
35 : : */
36 : 0 : static int key_wait_bit_intr(void *flags)
37 : : {
38 : 0 : schedule();
39 [ # # ]: 0 : return signal_pending(current) ? -ERESTARTSYS : 0;
40 : : }
41 : :
42 : : /**
43 : : * complete_request_key - Complete the construction of a key.
44 : : * @cons: The key construction record.
45 : : * @error: The success or failute of the construction.
46 : : *
47 : : * Complete the attempt to construct a key. The key will be negated
48 : : * if an error is indicated. The authorisation key will be revoked
49 : : * unconditionally.
50 : : */
51 : 0 : void complete_request_key(struct key_construction *cons, int error)
52 : : {
53 : : kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
54 : :
55 [ # # ]: 0 : if (error < 0)
56 : 0 : key_negate_and_link(cons->key, key_negative_timeout, NULL,
57 : : cons->authkey);
58 : : else
59 : 0 : key_revoke(cons->authkey);
60 : :
61 : 0 : key_put(cons->key);
62 : 0 : key_put(cons->authkey);
63 : 0 : kfree(cons);
64 : 0 : }
65 : : EXPORT_SYMBOL(complete_request_key);
66 : :
67 : : /*
68 : : * Initialise a usermode helper that is going to have a specific session
69 : : * keyring.
70 : : *
71 : : * This is called in context of freshly forked kthread before kernel_execve(),
72 : : * so we can simply install the desired session_keyring at this point.
73 : : */
74 : 0 : static int umh_keys_init(struct subprocess_info *info, struct cred *cred)
75 : : {
76 : 0 : struct key *keyring = info->data;
77 : :
78 : 0 : return install_session_keyring_to_cred(cred, keyring);
79 : : }
80 : :
81 : : /*
82 : : * Clean up a usermode helper with session keyring.
83 : : */
84 : 0 : static void umh_keys_cleanup(struct subprocess_info *info)
85 : : {
86 : 0 : struct key *keyring = info->data;
87 : 0 : key_put(keyring);
88 : 0 : }
89 : :
90 : : /*
91 : : * Call a usermode helper with a specific session keyring.
92 : : */
93 : 0 : static int call_usermodehelper_keys(char *path, char **argv, char **envp,
94 : : struct key *session_keyring, int wait)
95 : : {
96 : : struct subprocess_info *info;
97 : :
98 : 0 : info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL,
99 : : umh_keys_init, umh_keys_cleanup,
100 : : session_keyring);
101 [ # # ]: 0 : if (!info)
102 : : return -ENOMEM;
103 : :
104 : : key_get(session_keyring);
105 : 0 : return call_usermodehelper_exec(info, wait);
106 : : }
107 : :
108 : : /*
109 : : * Request userspace finish the construction of a key
110 : : * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
111 : : */
112 : 0 : static int call_sbin_request_key(struct key_construction *cons,
113 : : const char *op,
114 : : void *aux)
115 : : {
116 : : const struct cred *cred = current_cred();
117 : : key_serial_t prkey, sskey;
118 : 0 : struct key *key = cons->key, *authkey = cons->authkey, *keyring,
119 : : *session;
120 : : char *argv[9], *envp[3], uid_str[12], gid_str[12];
121 : : char key_str[12], keyring_str[3][12];
122 : : char desc[20];
123 : : int ret, i;
124 : :
125 : : kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
126 : :
127 : 0 : ret = install_user_keyrings();
128 [ # # ]: 0 : if (ret < 0)
129 : : goto error_alloc;
130 : :
131 : : /* allocate a new session keyring */
132 : 0 : sprintf(desc, "_req.%u", key->serial);
133 : :
134 : 0 : cred = get_current_cred();
135 : 0 : keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
136 : : KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
137 : : KEY_ALLOC_QUOTA_OVERRUN, NULL);
138 : : put_cred(cred);
139 [ # # ]: 0 : if (IS_ERR(keyring)) {
140 : : ret = PTR_ERR(keyring);
141 : 0 : goto error_alloc;
142 : : }
143 : :
144 : : /* attach the auth key to the session keyring */
145 : 0 : ret = key_link(keyring, authkey);
146 [ # # ]: 0 : if (ret < 0)
147 : : goto error_link;
148 : :
149 : : /* record the UID and GID */
150 : 0 : sprintf(uid_str, "%d", from_kuid(&init_user_ns, cred->fsuid));
151 : 0 : sprintf(gid_str, "%d", from_kgid(&init_user_ns, cred->fsgid));
152 : :
153 : : /* we say which key is under construction */
154 : 0 : sprintf(key_str, "%d", key->serial);
155 : :
156 : : /* we specify the process's default keyrings */
157 [ # # ]: 0 : sprintf(keyring_str[0], "%d",
158 : 0 : cred->thread_keyring ? cred->thread_keyring->serial : 0);
159 : :
160 : : prkey = 0;
161 [ # # ]: 0 : if (cred->process_keyring)
162 : 0 : prkey = cred->process_keyring->serial;
163 : 0 : sprintf(keyring_str[1], "%d", prkey);
164 : :
165 : : rcu_read_lock();
166 : 0 : session = rcu_dereference(cred->session_keyring);
167 [ # # ]: 0 : if (!session)
168 : 0 : session = cred->user->session_keyring;
169 : 0 : sskey = session->serial;
170 : : rcu_read_unlock();
171 : :
172 : 0 : sprintf(keyring_str[2], "%d", sskey);
173 : :
174 : : /* set up a minimal environment */
175 : : i = 0;
176 : 0 : envp[i++] = "HOME=/";
177 : 0 : envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
178 : 0 : envp[i] = NULL;
179 : :
180 : : /* set up the argument list */
181 : : i = 0;
182 : 0 : argv[i++] = "/sbin/request-key";
183 : 0 : argv[i++] = (char *) op;
184 : 0 : argv[i++] = key_str;
185 : 0 : argv[i++] = uid_str;
186 : 0 : argv[i++] = gid_str;
187 : 0 : argv[i++] = keyring_str[0];
188 : 0 : argv[i++] = keyring_str[1];
189 : 0 : argv[i++] = keyring_str[2];
190 : 0 : argv[i] = NULL;
191 : :
192 : : /* do it */
193 : 0 : ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
194 : : UMH_WAIT_PROC);
195 : : kdebug("usermode -> 0x%x", ret);
196 [ # # ]: 0 : if (ret >= 0) {
197 : : /* ret is the exit/wait code */
198 [ # # # # ]: 0 : if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
199 : 0 : key_validate(key) < 0)
200 : : ret = -ENOKEY;
201 : : else
202 : : /* ignore any errors from userspace if the key was
203 : : * instantiated */
204 : : ret = 0;
205 : : }
206 : :
207 : : error_link:
208 : 0 : key_put(keyring);
209 : :
210 : : error_alloc:
211 : 0 : complete_request_key(cons, ret);
212 : : kleave(" = %d", ret);
213 : 0 : return ret;
214 : : }
215 : :
216 : : /*
217 : : * Call out to userspace for key construction.
218 : : *
219 : : * Program failure is ignored in favour of key status.
220 : : */
221 : 0 : static int construct_key(struct key *key, const void *callout_info,
222 : : size_t callout_len, void *aux,
223 : : struct key *dest_keyring)
224 : : {
225 : : struct key_construction *cons;
226 : : request_key_actor_t actor;
227 : : struct key *authkey;
228 : : int ret;
229 : :
230 : : kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
231 : :
232 : : cons = kmalloc(sizeof(*cons), GFP_KERNEL);
233 [ # # ]: 0 : if (!cons)
234 : : return -ENOMEM;
235 : :
236 : : /* allocate an authorisation key */
237 : 0 : authkey = request_key_auth_new(key, callout_info, callout_len,
238 : : dest_keyring);
239 [ # # ]: 0 : if (IS_ERR(authkey)) {
240 : 0 : kfree(cons);
241 : : ret = PTR_ERR(authkey);
242 : : authkey = NULL;
243 : : } else {
244 : 0 : cons->authkey = key_get(authkey);
245 : 0 : cons->key = key_get(key);
246 : :
247 : : /* make the call */
248 : : actor = call_sbin_request_key;
249 [ # # ]: 0 : if (key->type->request_key)
250 : : actor = key->type->request_key;
251 : :
252 : 0 : ret = actor(cons, "create", aux);
253 : :
254 : : /* check that the actor called complete_request_key() prior to
255 : : * returning an error */
256 [ # # ][ # # ]: 0 : WARN_ON(ret < 0 &&
[ # # ]
257 : : !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
258 : 0 : key_put(authkey);
259 : : }
260 : :
261 : : kleave(" = %d", ret);
262 : 0 : return ret;
263 : : }
264 : :
265 : : /*
266 : : * Get the appropriate destination keyring for the request.
267 : : *
268 : : * The keyring selected is returned with an extra reference upon it which the
269 : : * caller must release.
270 : : */
271 : 0 : static void construct_get_dest_keyring(struct key **_dest_keyring)
272 : : {
273 : : struct request_key_auth *rka;
274 : 0 : const struct cred *cred = current_cred();
275 : 0 : struct key *dest_keyring = *_dest_keyring, *authkey;
276 : :
277 : : kenter("%p", dest_keyring);
278 : :
279 : : /* find the appropriate keyring */
280 [ # # ]: 0 : if (dest_keyring) {
281 : : /* the caller supplied one */
282 : : key_get(dest_keyring);
283 : : } else {
284 : : /* use a default keyring; falling through the cases until we
285 : : * find one that we actually have */
286 [ # # # # : 0 : switch (cred->jit_keyring) {
# # # ]
287 : : case KEY_REQKEY_DEFL_DEFAULT:
288 : : case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
289 [ # # ]: 0 : if (cred->request_key_auth) {
290 : : authkey = cred->request_key_auth;
291 : 0 : down_read(&authkey->sem);
292 : 0 : rka = authkey->payload.data;
293 [ # # ]: 0 : if (!test_bit(KEY_FLAG_REVOKED,
294 : : &authkey->flags))
295 : : dest_keyring =
296 : 0 : key_get(rka->dest_keyring);
297 : 0 : up_read(&authkey->sem);
298 [ # # ]: 0 : if (dest_keyring)
299 : : break;
300 : : }
301 : :
302 : : case KEY_REQKEY_DEFL_THREAD_KEYRING:
303 : 0 : dest_keyring = key_get(cred->thread_keyring);
304 [ # # ]: 0 : if (dest_keyring)
305 : : break;
306 : :
307 : : case KEY_REQKEY_DEFL_PROCESS_KEYRING:
308 : 0 : dest_keyring = key_get(cred->process_keyring);
309 [ # # ]: 0 : if (dest_keyring)
310 : : break;
311 : :
312 : : case KEY_REQKEY_DEFL_SESSION_KEYRING:
313 : : rcu_read_lock();
314 : : dest_keyring = key_get(
315 : 0 : rcu_dereference(cred->session_keyring));
316 : : rcu_read_unlock();
317 : :
318 [ # # ]: 0 : if (dest_keyring)
319 : : break;
320 : :
321 : : case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
322 : : dest_keyring =
323 : 0 : key_get(cred->user->session_keyring);
324 : 0 : break;
325 : :
326 : : case KEY_REQKEY_DEFL_USER_KEYRING:
327 : 0 : dest_keyring = key_get(cred->user->uid_keyring);
328 : 0 : break;
329 : :
330 : : case KEY_REQKEY_DEFL_GROUP_KEYRING:
331 : : default:
332 : 0 : BUG();
333 : : }
334 : : }
335 : :
336 : 0 : *_dest_keyring = dest_keyring;
337 : : kleave(" [dk %d]", key_serial(dest_keyring));
338 : 0 : return;
339 : : }
340 : :
341 : : /*
342 : : * Allocate a new key in under-construction state and attempt to link it in to
343 : : * the requested keyring.
344 : : *
345 : : * May return a key that's already under construction instead if there was a
346 : : * race between two thread calling request_key().
347 : : */
348 : 0 : static int construct_alloc_key(struct keyring_search_context *ctx,
349 : : struct key *dest_keyring,
350 : : unsigned long flags,
351 : : struct key_user *user,
352 : : struct key **_key)
353 : : {
354 : : struct assoc_array_edit *edit;
355 : : struct key *key;
356 : : key_perm_t perm;
357 : : key_ref_t key_ref;
358 : : int ret;
359 : :
360 : : kenter("%s,%s,,,",
361 : : ctx->index_key.type->name, ctx->index_key.description);
362 : :
363 : 0 : *_key = NULL;
364 : 0 : mutex_lock(&user->cons_lock);
365 : :
366 : : perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
367 : : perm |= KEY_USR_VIEW;
368 [ # # ]: 0 : if (ctx->index_key.type->read)
369 : : perm |= KEY_POS_READ;
370 [ # # ][ # # ]: 0 : if (ctx->index_key.type == &key_type_keyring ||
371 : 0 : ctx->index_key.type->update)
372 : 0 : perm |= KEY_POS_WRITE;
373 : :
374 : 0 : key = key_alloc(ctx->index_key.type, ctx->index_key.description,
375 : : ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
376 : : perm, flags);
377 [ # # ]: 0 : if (IS_ERR(key))
378 : : goto alloc_failed;
379 : :
380 : 0 : set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
381 : :
382 [ # # ]: 0 : if (dest_keyring) {
383 : 0 : ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit);
384 [ # # ]: 0 : if (ret < 0)
385 : : goto link_prealloc_failed;
386 : : }
387 : :
388 : : /* attach the key to the destination keyring under lock, but we do need
389 : : * to do another check just in case someone beat us to it whilst we
390 : : * waited for locks */
391 : 0 : mutex_lock(&key_construction_mutex);
392 : :
393 : 0 : key_ref = search_process_keyrings(ctx);
394 [ # # ]: 0 : if (!IS_ERR(key_ref))
395 : : goto key_already_present;
396 : :
397 [ # # ]: 0 : if (dest_keyring)
398 : 0 : __key_link(key, &edit);
399 : :
400 : 0 : mutex_unlock(&key_construction_mutex);
401 [ # # ]: 0 : if (dest_keyring)
402 : 0 : __key_link_end(dest_keyring, &ctx->index_key, edit);
403 : 0 : mutex_unlock(&user->cons_lock);
404 : 0 : *_key = key;
405 : : kleave(" = 0 [%d]", key_serial(key));
406 : : return 0;
407 : :
408 : : /* the key is now present - we tell the caller that we found it by
409 : : * returning -EINPROGRESS */
410 : : key_already_present:
411 : 0 : key_put(key);
412 : 0 : mutex_unlock(&key_construction_mutex);
413 : : key = key_ref_to_ptr(key_ref);
414 [ # # ]: 0 : if (dest_keyring) {
415 : 0 : ret = __key_link_check_live_key(dest_keyring, key);
416 [ # # ]: 0 : if (ret == 0)
417 : 0 : __key_link(key, &edit);
418 : 0 : __key_link_end(dest_keyring, &ctx->index_key, edit);
419 [ # # ]: 0 : if (ret < 0)
420 : : goto link_check_failed;
421 : : }
422 : 0 : mutex_unlock(&user->cons_lock);
423 : 0 : *_key = key;
424 : : kleave(" = -EINPROGRESS [%d]", key_serial(key));
425 : : return -EINPROGRESS;
426 : :
427 : : link_check_failed:
428 : 0 : mutex_unlock(&user->cons_lock);
429 : 0 : key_put(key);
430 : : kleave(" = %d [linkcheck]", ret);
431 : 0 : return ret;
432 : :
433 : : link_prealloc_failed:
434 : 0 : mutex_unlock(&user->cons_lock);
435 : : kleave(" = %d [prelink]", ret);
436 : 0 : return ret;
437 : :
438 : : alloc_failed:
439 : 0 : mutex_unlock(&user->cons_lock);
440 : : kleave(" = %ld", PTR_ERR(key));
441 : 0 : return PTR_ERR(key);
442 : : }
443 : :
444 : : /*
445 : : * Commence key construction.
446 : : */
447 : 0 : static struct key *construct_key_and_link(struct keyring_search_context *ctx,
448 : : const char *callout_info,
449 : : size_t callout_len,
450 : : void *aux,
451 : : struct key *dest_keyring,
452 : : unsigned long flags)
453 : : {
454 : : struct key_user *user;
455 : : struct key *key;
456 : : int ret;
457 : :
458 : : kenter("");
459 : :
460 : 0 : user = key_user_lookup(current_fsuid());
461 [ # # ]: 0 : if (!user)
462 : : return ERR_PTR(-ENOMEM);
463 : :
464 : 0 : construct_get_dest_keyring(&dest_keyring);
465 : :
466 : 0 : ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
467 : 0 : key_user_put(user);
468 : :
469 [ # # ]: 0 : if (ret == 0) {
470 : 0 : ret = construct_key(key, callout_info, callout_len, aux,
471 : : dest_keyring);
472 [ # # ]: 0 : if (ret < 0) {
473 : : kdebug("cons failed");
474 : : goto construction_failed;
475 : : }
476 [ # # ]: 0 : } else if (ret == -EINPROGRESS) {
477 : : ret = 0;
478 : : } else {
479 : : goto couldnt_alloc_key;
480 : : }
481 : :
482 : 0 : key_put(dest_keyring);
483 : 0 : kleave(" = key %d", key_serial(key));
484 : 0 : return key;
485 : :
486 : : construction_failed:
487 : 0 : key_negate_and_link(key, key_negative_timeout, NULL, NULL);
488 : 0 : key_put(key);
489 : : couldnt_alloc_key:
490 : 0 : key_put(dest_keyring);
491 : : kleave(" = %d", ret);
492 : 0 : return ERR_PTR(ret);
493 : : }
494 : :
495 : : /**
496 : : * request_key_and_link - Request a key and cache it in a keyring.
497 : : * @type: The type of key we want.
498 : : * @description: The searchable description of the key.
499 : : * @callout_info: The data to pass to the instantiation upcall (or NULL).
500 : : * @callout_len: The length of callout_info.
501 : : * @aux: Auxiliary data for the upcall.
502 : : * @dest_keyring: Where to cache the key.
503 : : * @flags: Flags to key_alloc().
504 : : *
505 : : * A key matching the specified criteria is searched for in the process's
506 : : * keyrings and returned with its usage count incremented if found. Otherwise,
507 : : * if callout_info is not NULL, a key will be allocated and some service
508 : : * (probably in userspace) will be asked to instantiate it.
509 : : *
510 : : * If successfully found or created, the key will be linked to the destination
511 : : * keyring if one is provided.
512 : : *
513 : : * Returns a pointer to the key if successful; -EACCES, -ENOKEY, -EKEYREVOKED
514 : : * or -EKEYEXPIRED if an inaccessible, negative, revoked or expired key was
515 : : * found; -ENOKEY if no key was found and no @callout_info was given; -EDQUOT
516 : : * if insufficient key quota was available to create a new key; or -ENOMEM if
517 : : * insufficient memory was available.
518 : : *
519 : : * If the returned key was created, then it may still be under construction,
520 : : * and wait_for_key_construction() should be used to wait for that to complete.
521 : : */
522 : 0 : struct key *request_key_and_link(struct key_type *type,
523 : : const char *description,
524 : : const void *callout_info,
525 : : size_t callout_len,
526 : : void *aux,
527 : : struct key *dest_keyring,
528 : : unsigned long flags)
529 : : {
530 : 0 : struct keyring_search_context ctx = {
531 : : .index_key.type = type,
532 : : .index_key.description = description,
533 : 0 : .cred = current_cred(),
534 : 0 : .match = type->match,
535 : : .match_data = description,
536 : : .flags = KEYRING_SEARCH_LOOKUP_DIRECT,
537 : : };
538 : : struct key *key;
539 : : key_ref_t key_ref;
540 : : int ret;
541 : :
542 : : kenter("%s,%s,%p,%zu,%p,%p,%lx",
543 : : ctx.index_key.type->name, ctx.index_key.description,
544 : : callout_info, callout_len, aux, dest_keyring, flags);
545 : :
546 : : /* search all the process keyrings for a key */
547 : 0 : key_ref = search_process_keyrings(&ctx);
548 : :
549 [ # # ]: 0 : if (!IS_ERR(key_ref)) {
550 : : key = key_ref_to_ptr(key_ref);
551 [ # # ]: 0 : if (dest_keyring) {
552 : 0 : construct_get_dest_keyring(&dest_keyring);
553 : 0 : ret = key_link(dest_keyring, key);
554 : 0 : key_put(dest_keyring);
555 [ # # ]: 0 : if (ret < 0) {
556 : 0 : key_put(key);
557 : : key = ERR_PTR(ret);
558 : 0 : goto error;
559 : : }
560 : : }
561 [ # # ]: 0 : } else if (PTR_ERR(key_ref) != -EAGAIN) {
562 : : key = ERR_CAST(key_ref);
563 : : } else {
564 : : /* the search failed, but the keyrings were searchable, so we
565 : : * should consult userspace if we can */
566 : : key = ERR_PTR(-ENOKEY);
567 [ # # ]: 0 : if (!callout_info)
568 : : goto error;
569 : :
570 : 0 : key = construct_key_and_link(&ctx, callout_info, callout_len,
571 : : aux, dest_keyring, flags);
572 : : }
573 : :
574 : : error:
575 : : kleave(" = %p", key);
576 : 0 : return key;
577 : : }
578 : :
579 : : /**
580 : : * wait_for_key_construction - Wait for construction of a key to complete
581 : : * @key: The key being waited for.
582 : : * @intr: Whether to wait interruptibly.
583 : : *
584 : : * Wait for a key to finish being constructed.
585 : : *
586 : : * Returns 0 if successful; -ERESTARTSYS if the wait was interrupted; -ENOKEY
587 : : * if the key was negated; or -EKEYREVOKED or -EKEYEXPIRED if the key was
588 : : * revoked or expired.
589 : : */
590 : 0 : int wait_for_key_construction(struct key *key, bool intr)
591 : : {
592 : : int ret;
593 : :
594 [ - + ][ - + ]: 2 : ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
595 : : intr ? key_wait_bit_intr : key_wait_bit,
596 : : intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
597 [ + - ]: 2 : if (ret < 0)
598 : : return ret;
599 [ - + ]: 2 : if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
600 : 0 : smp_rmb();
601 : 0 : return key->type_data.reject_error;
602 : : }
603 : 2 : return key_validate(key);
604 : : }
605 : : EXPORT_SYMBOL(wait_for_key_construction);
606 : :
607 : : /**
608 : : * request_key - Request a key and wait for construction
609 : : * @type: Type of key.
610 : : * @description: The searchable description of the key.
611 : : * @callout_info: The data to pass to the instantiation upcall (or NULL).
612 : : *
613 : : * As for request_key_and_link() except that it does not add the returned key
614 : : * to a keyring if found, new keys are always allocated in the user's quota,
615 : : * the callout_info must be a NUL-terminated string and no auxiliary data can
616 : : * be passed.
617 : : *
618 : : * Furthermore, it then works as wait_for_key_construction() to wait for the
619 : : * completion of keys undergoing construction with a non-interruptible wait.
620 : : */
621 : 0 : struct key *request_key(struct key_type *type,
622 : : const char *description,
623 : : const char *callout_info)
624 : : {
625 : : struct key *key;
626 : : size_t callout_len = 0;
627 : : int ret;
628 : :
629 [ # # ]: 0 : if (callout_info)
630 : 0 : callout_len = strlen(callout_info);
631 : 0 : key = request_key_and_link(type, description, callout_info, callout_len,
632 : : NULL, NULL, KEY_ALLOC_IN_QUOTA);
633 [ # # ]: 0 : if (!IS_ERR(key)) {
634 : 0 : ret = wait_for_key_construction(key, false);
635 [ # # ]: 0 : if (ret < 0) {
636 : 0 : key_put(key);
637 : 0 : return ERR_PTR(ret);
638 : : }
639 : : }
640 : 0 : return key;
641 : : }
642 : : EXPORT_SYMBOL(request_key);
643 : :
644 : : /**
645 : : * request_key_with_auxdata - Request a key with auxiliary data for the upcaller
646 : : * @type: The type of key we want.
647 : : * @description: The searchable description of the key.
648 : : * @callout_info: The data to pass to the instantiation upcall (or NULL).
649 : : * @callout_len: The length of callout_info.
650 : : * @aux: Auxiliary data for the upcall.
651 : : *
652 : : * As for request_key_and_link() except that it does not add the returned key
653 : : * to a keyring if found and new keys are always allocated in the user's quota.
654 : : *
655 : : * Furthermore, it then works as wait_for_key_construction() to wait for the
656 : : * completion of keys undergoing construction with a non-interruptible wait.
657 : : */
658 : 0 : struct key *request_key_with_auxdata(struct key_type *type,
659 : : const char *description,
660 : : const void *callout_info,
661 : : size_t callout_len,
662 : : void *aux)
663 : : {
664 : : struct key *key;
665 : : int ret;
666 : :
667 : 0 : key = request_key_and_link(type, description, callout_info, callout_len,
668 : : aux, NULL, KEY_ALLOC_IN_QUOTA);
669 [ # # ]: 0 : if (!IS_ERR(key)) {
670 : 0 : ret = wait_for_key_construction(key, false);
671 [ # # ]: 0 : if (ret < 0) {
672 : 0 : key_put(key);
673 : 0 : return ERR_PTR(ret);
674 : : }
675 : : }
676 : 0 : return key;
677 : : }
678 : : EXPORT_SYMBOL(request_key_with_auxdata);
679 : :
680 : : /*
681 : : * request_key_async - Request a key (allow async construction)
682 : : * @type: Type of key.
683 : : * @description: The searchable description of the key.
684 : : * @callout_info: The data to pass to the instantiation upcall (or NULL).
685 : : * @callout_len: The length of callout_info.
686 : : *
687 : : * As for request_key_and_link() except that it does not add the returned key
688 : : * to a keyring if found, new keys are always allocated in the user's quota and
689 : : * no auxiliary data can be passed.
690 : : *
691 : : * The caller should call wait_for_key_construction() to wait for the
692 : : * completion of the returned key if it is still undergoing construction.
693 : : */
694 : 0 : struct key *request_key_async(struct key_type *type,
695 : : const char *description,
696 : : const void *callout_info,
697 : : size_t callout_len)
698 : : {
699 : 0 : return request_key_and_link(type, description, callout_info,
700 : : callout_len, NULL, NULL,
701 : : KEY_ALLOC_IN_QUOTA);
702 : : }
703 : : EXPORT_SYMBOL(request_key_async);
704 : :
705 : : /*
706 : : * request a key with auxiliary data for the upcaller (allow async construction)
707 : : * @type: Type of key.
708 : : * @description: The searchable description of the key.
709 : : * @callout_info: The data to pass to the instantiation upcall (or NULL).
710 : : * @callout_len: The length of callout_info.
711 : : * @aux: Auxiliary data for the upcall.
712 : : *
713 : : * As for request_key_and_link() except that it does not add the returned key
714 : : * to a keyring if found and new keys are always allocated in the user's quota.
715 : : *
716 : : * The caller should call wait_for_key_construction() to wait for the
717 : : * completion of the returned key if it is still undergoing construction.
718 : : */
719 : 0 : struct key *request_key_async_with_auxdata(struct key_type *type,
720 : : const char *description,
721 : : const void *callout_info,
722 : : size_t callout_len,
723 : : void *aux)
724 : : {
725 : 0 : return request_key_and_link(type, description, callout_info,
726 : : callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
727 : : }
728 : : EXPORT_SYMBOL(request_key_async_with_auxdata);
|