request_key.c (16feef4340172b7dbb9cba60850e78fa6388adf1) request_key.c (4bdf0bc300314141e5475e145acb8b5ad846f00d)
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

--- 331 unchanged lines hidden (view full) ---

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 */
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

--- 331 unchanged lines hidden (view full) ---

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 */
348static int construct_alloc_key(struct key_type *type,
349 const char *description,
348static int construct_alloc_key(struct keyring_search_context *ctx,
350 struct key *dest_keyring,
351 unsigned long flags,
352 struct key_user *user,
353 struct key **_key)
354{
349 struct key *dest_keyring,
350 unsigned long flags,
351 struct key_user *user,
352 struct key **_key)
353{
355 const struct keyring_index_key index_key = {
356 .type = type,
357 .description = description,
358 .desc_len = strlen(description),
359 };
360 const struct cred *cred = current_cred();
361 unsigned long prealloc;
362 struct key *key;
363 key_perm_t perm;
364 key_ref_t key_ref;
365 int ret;
366
354 unsigned long prealloc;
355 struct key *key;
356 key_perm_t perm;
357 key_ref_t key_ref;
358 int ret;
359
367 kenter("%s,%s,,,", type->name, description);
360 kenter("%s,%s,,,",
361 ctx->index_key.type->name, ctx->index_key.description);
368
369 *_key = NULL;
370 mutex_lock(&user->cons_lock);
371
372 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
373 perm |= KEY_USR_VIEW;
362
363 *_key = NULL;
364 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;
374 if (type->read)
368 if (ctx->index_key.type->read)
375 perm |= KEY_POS_READ;
369 perm |= KEY_POS_READ;
376 if (type == &key_type_keyring || type->update)
370 if (ctx->index_key.type == &key_type_keyring ||
371 ctx->index_key.type->update)
377 perm |= KEY_POS_WRITE;
378
372 perm |= KEY_POS_WRITE;
373
379 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
374 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
375 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
380 perm, flags);
381 if (IS_ERR(key))
382 goto alloc_failed;
383
384 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
385
386 if (dest_keyring) {
376 perm, flags);
377 if (IS_ERR(key))
378 goto alloc_failed;
379
380 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
381
382 if (dest_keyring) {
387 ret = __key_link_begin(dest_keyring, &index_key, &prealloc);
383 ret = __key_link_begin(dest_keyring, &ctx->index_key, &prealloc);
388 if (ret < 0)
389 goto link_prealloc_failed;
390 }
391
392 /* attach the key to the destination keyring under lock, but we do need
393 * to do another check just in case someone beat us to it whilst we
394 * waited for locks */
395 mutex_lock(&key_construction_mutex);
396
384 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 mutex_lock(&key_construction_mutex);
392
397 key_ref = search_process_keyrings(type, description, type->match,
398 false, cred);
393 key_ref = search_process_keyrings(ctx);
399 if (!IS_ERR(key_ref))
400 goto key_already_present;
401
402 if (dest_keyring)
403 __key_link(dest_keyring, key, &prealloc);
404
405 mutex_unlock(&key_construction_mutex);
406 if (dest_keyring)
394 if (!IS_ERR(key_ref))
395 goto key_already_present;
396
397 if (dest_keyring)
398 __key_link(dest_keyring, key, &prealloc);
399
400 mutex_unlock(&key_construction_mutex);
401 if (dest_keyring)
407 __key_link_end(dest_keyring, &index_key, prealloc);
402 __key_link_end(dest_keyring, &ctx->index_key, prealloc);
408 mutex_unlock(&user->cons_lock);
409 *_key = key;
410 kleave(" = 0 [%d]", key_serial(key));
411 return 0;
412
413 /* the key is now present - we tell the caller that we found it by
414 * returning -EINPROGRESS */
415key_already_present:
416 key_put(key);
417 mutex_unlock(&key_construction_mutex);
418 key = key_ref_to_ptr(key_ref);
419 if (dest_keyring) {
420 ret = __key_link_check_live_key(dest_keyring, key);
421 if (ret == 0)
422 __key_link(dest_keyring, key, &prealloc);
403 mutex_unlock(&user->cons_lock);
404 *_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 */
410key_already_present:
411 key_put(key);
412 mutex_unlock(&key_construction_mutex);
413 key = key_ref_to_ptr(key_ref);
414 if (dest_keyring) {
415 ret = __key_link_check_live_key(dest_keyring, key);
416 if (ret == 0)
417 __key_link(dest_keyring, key, &prealloc);
423 __key_link_end(dest_keyring, &index_key, prealloc);
418 __key_link_end(dest_keyring, &ctx->index_key, prealloc);
424 if (ret < 0)
425 goto link_check_failed;
426 }
427 mutex_unlock(&user->cons_lock);
428 *_key = key;
429 kleave(" = -EINPROGRESS [%d]", key_serial(key));
430 return -EINPROGRESS;
431

--- 12 unchanged lines hidden (view full) ---

444 mutex_unlock(&user->cons_lock);
445 kleave(" = %ld", PTR_ERR(key));
446 return PTR_ERR(key);
447}
448
449/*
450 * Commence key construction.
451 */
419 if (ret < 0)
420 goto link_check_failed;
421 }
422 mutex_unlock(&user->cons_lock);
423 *_key = key;
424 kleave(" = -EINPROGRESS [%d]", key_serial(key));
425 return -EINPROGRESS;
426

--- 12 unchanged lines hidden (view full) ---

439 mutex_unlock(&user->cons_lock);
440 kleave(" = %ld", PTR_ERR(key));
441 return PTR_ERR(key);
442}
443
444/*
445 * Commence key construction.
446 */
452static struct key *construct_key_and_link(struct key_type *type,
453 const char *description,
447static struct key *construct_key_and_link(struct keyring_search_context *ctx,
454 const char *callout_info,
455 size_t callout_len,
456 void *aux,
457 struct key *dest_keyring,
458 unsigned long flags)
459{
460 struct key_user *user;
461 struct key *key;
462 int ret;
463
464 kenter("");
465
466 user = key_user_lookup(current_fsuid());
467 if (!user)
468 return ERR_PTR(-ENOMEM);
469
470 construct_get_dest_keyring(&dest_keyring);
471
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 user = key_user_lookup(current_fsuid());
461 if (!user)
462 return ERR_PTR(-ENOMEM);
463
464 construct_get_dest_keyring(&dest_keyring);
465
472 ret = construct_alloc_key(type, description, dest_keyring, flags, user,
473 &key);
466 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
474 key_user_put(user);
475
476 if (ret == 0) {
477 ret = construct_key(key, callout_info, callout_len, aux,
478 dest_keyring);
479 if (ret < 0) {
480 kdebug("cons failed");
481 goto construction_failed;

--- 47 unchanged lines hidden (view full) ---

529struct key *request_key_and_link(struct key_type *type,
530 const char *description,
531 const void *callout_info,
532 size_t callout_len,
533 void *aux,
534 struct key *dest_keyring,
535 unsigned long flags)
536{
467 key_user_put(user);
468
469 if (ret == 0) {
470 ret = construct_key(key, callout_info, callout_len, aux,
471 dest_keyring);
472 if (ret < 0) {
473 kdebug("cons failed");
474 goto construction_failed;

--- 47 unchanged lines hidden (view full) ---

522struct 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{
537 const struct cred *cred = current_cred();
530 struct keyring_search_context ctx = {
531 .index_key.type = type,
532 .index_key.description = description,
533 .cred = current_cred(),
534 .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",
538 struct key *key;
539 key_ref_t key_ref;
540 int ret;
541
542 kenter("%s,%s,%p,%zu,%p,%p,%lx",
543 type->name, description, callout_info, callout_len, aux,
544 dest_keyring, flags);
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 */
545
546 /* search all the process keyrings for a key */
547 key_ref = search_process_keyrings(type, description, type->match,
548 false, cred);
547 key_ref = search_process_keyrings(&ctx);
549
550 if (!IS_ERR(key_ref)) {
551 key = key_ref_to_ptr(key_ref);
552 if (dest_keyring) {
553 construct_get_dest_keyring(&dest_keyring);
554 ret = key_link(dest_keyring, key);
555 key_put(dest_keyring);
556 if (ret < 0) {

--- 6 unchanged lines hidden (view full) ---

563 key = ERR_CAST(key_ref);
564 } else {
565 /* the search failed, but the keyrings were searchable, so we
566 * should consult userspace if we can */
567 key = ERR_PTR(-ENOKEY);
568 if (!callout_info)
569 goto error;
570
548
549 if (!IS_ERR(key_ref)) {
550 key = key_ref_to_ptr(key_ref);
551 if (dest_keyring) {
552 construct_get_dest_keyring(&dest_keyring);
553 ret = key_link(dest_keyring, key);
554 key_put(dest_keyring);
555 if (ret < 0) {

--- 6 unchanged lines hidden (view full) ---

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 if (!callout_info)
568 goto error;
569
571 key = construct_key_and_link(type, description, callout_info,
572 callout_len, aux, dest_keyring,
573 flags);
570 key = construct_key_and_link(&ctx, callout_info, callout_len,
571 aux, dest_keyring, flags);
574 }
575
576error:
577 kleave(" = %p", key);
578 return key;
579}
580
581/**

--- 147 unchanged lines hidden ---
572 }
573
574error:
575 kleave(" = %p", key);
576 return key;
577}
578
579/**

--- 147 unchanged lines hidden ---