process_keys.c (61ea0c0ba904a55f55317d850c1072ff7835ac92) process_keys.c (4bdf0bc300314141e5475e145acb8b5ad846f00d)
1/* Manage a process's keyrings
2 *
3 * Copyright (C) 2004-2005, 2008 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

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

314 *
315 * Returns a pointer to the key with the key usage count incremented if
316 * successful, -EAGAIN if we didn't find any matching key or -ENOKEY if we only
317 * matched negative keys.
318 *
319 * In the case of a successful return, the possession attribute is set on the
320 * returned key reference.
321 */
1/* Manage a process's keyrings
2 *
3 * Copyright (C) 2004-2005, 2008 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

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

314 *
315 * Returns a pointer to the key with the key usage count incremented if
316 * successful, -EAGAIN if we didn't find any matching key or -ENOKEY if we only
317 * matched negative keys.
318 *
319 * In the case of a successful return, the possession attribute is set on the
320 * returned key reference.
321 */
322key_ref_t search_my_process_keyrings(struct key_type *type,
323 const void *description,
324 key_match_func_t match,
325 bool no_state_check,
326 const struct cred *cred)
322key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
327{
328 key_ref_t key_ref, ret, err;
329
330 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
331 * searchable, but we failed to find a key or we found a negative key;
332 * otherwise we want to return a sample error (probably -EACCES) if
333 * none of the keyrings were searchable
334 *
335 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
336 */
337 key_ref = NULL;
338 ret = NULL;
339 err = ERR_PTR(-EAGAIN);
340
341 /* search the thread keyring first */
323{
324 key_ref_t key_ref, ret, err;
325
326 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
327 * searchable, but we failed to find a key or we found a negative key;
328 * otherwise we want to return a sample error (probably -EACCES) if
329 * none of the keyrings were searchable
330 *
331 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
332 */
333 key_ref = NULL;
334 ret = NULL;
335 err = ERR_PTR(-EAGAIN);
336
337 /* search the thread keyring first */
342 if (cred->thread_keyring) {
338 if (ctx->cred->thread_keyring) {
343 key_ref = keyring_search_aux(
339 key_ref = keyring_search_aux(
344 make_key_ref(cred->thread_keyring, 1),
345 cred, type, description, match, no_state_check);
340 make_key_ref(ctx->cred->thread_keyring, 1), ctx);
346 if (!IS_ERR(key_ref))
347 goto found;
348
349 switch (PTR_ERR(key_ref)) {
350 case -EAGAIN: /* no key */
351 case -ENOKEY: /* negative key */
352 ret = key_ref;
353 break;
354 default:
355 err = key_ref;
356 break;
357 }
358 }
359
360 /* search the process keyring second */
341 if (!IS_ERR(key_ref))
342 goto found;
343
344 switch (PTR_ERR(key_ref)) {
345 case -EAGAIN: /* no key */
346 case -ENOKEY: /* negative key */
347 ret = key_ref;
348 break;
349 default:
350 err = key_ref;
351 break;
352 }
353 }
354
355 /* search the process keyring second */
361 if (cred->process_keyring) {
356 if (ctx->cred->process_keyring) {
362 key_ref = keyring_search_aux(
357 key_ref = keyring_search_aux(
363 make_key_ref(cred->process_keyring, 1),
364 cred, type, description, match, no_state_check);
358 make_key_ref(ctx->cred->process_keyring, 1), ctx);
365 if (!IS_ERR(key_ref))
366 goto found;
367
368 switch (PTR_ERR(key_ref)) {
369 case -EAGAIN: /* no key */
370 if (ret)
371 break;
372 case -ENOKEY: /* negative key */
373 ret = key_ref;
374 break;
375 default:
376 err = key_ref;
377 break;
378 }
379 }
380
381 /* search the session keyring */
359 if (!IS_ERR(key_ref))
360 goto found;
361
362 switch (PTR_ERR(key_ref)) {
363 case -EAGAIN: /* no key */
364 if (ret)
365 break;
366 case -ENOKEY: /* negative key */
367 ret = key_ref;
368 break;
369 default:
370 err = key_ref;
371 break;
372 }
373 }
374
375 /* search the session keyring */
382 if (cred->session_keyring) {
376 if (ctx->cred->session_keyring) {
383 rcu_read_lock();
384 key_ref = keyring_search_aux(
377 rcu_read_lock();
378 key_ref = keyring_search_aux(
385 make_key_ref(rcu_dereference(cred->session_keyring), 1),
386 cred, type, description, match, no_state_check);
379 make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1),
380 ctx);
387 rcu_read_unlock();
388
389 if (!IS_ERR(key_ref))
390 goto found;
391
392 switch (PTR_ERR(key_ref)) {
393 case -EAGAIN: /* no key */
394 if (ret)
395 break;
396 case -ENOKEY: /* negative key */
397 ret = key_ref;
398 break;
399 default:
400 err = key_ref;
401 break;
402 }
403 }
404 /* or search the user-session keyring */
381 rcu_read_unlock();
382
383 if (!IS_ERR(key_ref))
384 goto found;
385
386 switch (PTR_ERR(key_ref)) {
387 case -EAGAIN: /* no key */
388 if (ret)
389 break;
390 case -ENOKEY: /* negative key */
391 ret = key_ref;
392 break;
393 default:
394 err = key_ref;
395 break;
396 }
397 }
398 /* or search the user-session keyring */
405 else if (cred->user->session_keyring) {
399 else if (ctx->cred->user->session_keyring) {
406 key_ref = keyring_search_aux(
400 key_ref = keyring_search_aux(
407 make_key_ref(cred->user->session_keyring, 1),
408 cred, type, description, match, no_state_check);
401 make_key_ref(ctx->cred->user->session_keyring, 1),
402 ctx);
409 if (!IS_ERR(key_ref))
410 goto found;
411
412 switch (PTR_ERR(key_ref)) {
413 case -EAGAIN: /* no key */
414 if (ret)
415 break;
416 case -ENOKEY: /* negative key */

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

432/*
433 * Search the process keyrings attached to the supplied cred for the first
434 * matching key in the manner of search_my_process_keyrings(), but also search
435 * the keys attached to the assumed authorisation key using its credentials if
436 * one is available.
437 *
438 * Return same as search_my_process_keyrings().
439 */
403 if (!IS_ERR(key_ref))
404 goto found;
405
406 switch (PTR_ERR(key_ref)) {
407 case -EAGAIN: /* no key */
408 if (ret)
409 break;
410 case -ENOKEY: /* negative key */

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

426/*
427 * Search the process keyrings attached to the supplied cred for the first
428 * matching key in the manner of search_my_process_keyrings(), but also search
429 * the keys attached to the assumed authorisation key using its credentials if
430 * one is available.
431 *
432 * Return same as search_my_process_keyrings().
433 */
440key_ref_t search_process_keyrings(struct key_type *type,
441 const void *description,
442 key_match_func_t match,
443 bool no_state_check,
444 const struct cred *cred)
434key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
445{
446 struct request_key_auth *rka;
447 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
448
449 might_sleep();
450
435{
436 struct request_key_auth *rka;
437 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
438
439 might_sleep();
440
451 key_ref = search_my_process_keyrings(type, description, match,
452 no_state_check, cred);
441 key_ref = search_my_process_keyrings(ctx);
453 if (!IS_ERR(key_ref))
454 goto found;
455 err = key_ref;
456
457 /* if this process has an instantiation authorisation key, then we also
458 * search the keyrings of the process mentioned there
459 * - we don't permit access to request_key auth keys via this method
460 */
442 if (!IS_ERR(key_ref))
443 goto found;
444 err = key_ref;
445
446 /* if this process has an instantiation authorisation key, then we also
447 * search the keyrings of the process mentioned there
448 * - we don't permit access to request_key auth keys via this method
449 */
461 if (cred->request_key_auth &&
462 cred == current_cred() &&
463 type != &key_type_request_key_auth
450 if (ctx->cred->request_key_auth &&
451 ctx->cred == current_cred() &&
452 ctx->index_key.type != &key_type_request_key_auth
464 ) {
453 ) {
454 const struct cred *cred = ctx->cred;
455
465 /* defend against the auth key being revoked */
466 down_read(&cred->request_key_auth->sem);
467
456 /* defend against the auth key being revoked */
457 down_read(&cred->request_key_auth->sem);
458
468 if (key_validate(cred->request_key_auth) == 0) {
469 rka = cred->request_key_auth->payload.data;
459 if (key_validate(ctx->cred->request_key_auth) == 0) {
460 rka = ctx->cred->request_key_auth->payload.data;
470
461
471 key_ref = search_process_keyrings(type, description,
472 match, no_state_check,
473 rka->cred);
462 ctx->cred = rka->cred;
463 key_ref = search_process_keyrings(ctx);
464 ctx->cred = cred;
474
475 up_read(&cred->request_key_auth->sem);
476
477 if (!IS_ERR(key_ref))
478 goto found;
479
480 ret = key_ref;
481 } else {

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

519 * or -ENOMEM if a special keyring couldn't be created.
520 *
521 * In the case of a successful return, the possession attribute is set on the
522 * returned key reference.
523 */
524key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
525 key_perm_t perm)
526{
465
466 up_read(&cred->request_key_auth->sem);
467
468 if (!IS_ERR(key_ref))
469 goto found;
470
471 ret = key_ref;
472 } else {

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

510 * or -ENOMEM if a special keyring couldn't be created.
511 *
512 * In the case of a successful return, the possession attribute is set on the
513 * returned key reference.
514 */
515key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
516 key_perm_t perm)
517{
518 struct keyring_search_context ctx = {
519 .match = lookup_user_key_possessed,
520 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
521 KEYRING_SEARCH_LOOKUP_DIRECT),
522 };
527 struct request_key_auth *rka;
523 struct request_key_auth *rka;
528 const struct cred *cred;
529 struct key *key;
530 key_ref_t key_ref, skey_ref;
531 int ret;
532
533try_again:
524 struct key *key;
525 key_ref_t key_ref, skey_ref;
526 int ret;
527
528try_again:
534 cred = get_current_cred();
529 ctx.cred = get_current_cred();
535 key_ref = ERR_PTR(-ENOKEY);
536
537 switch (id) {
538 case KEY_SPEC_THREAD_KEYRING:
530 key_ref = ERR_PTR(-ENOKEY);
531
532 switch (id) {
533 case KEY_SPEC_THREAD_KEYRING:
539 if (!cred->thread_keyring) {
534 if (!ctx.cred->thread_keyring) {
540 if (!(lflags & KEY_LOOKUP_CREATE))
541 goto error;
542
543 ret = install_thread_keyring();
544 if (ret < 0) {
545 key_ref = ERR_PTR(ret);
546 goto error;
547 }
548 goto reget_creds;
549 }
550
535 if (!(lflags & KEY_LOOKUP_CREATE))
536 goto error;
537
538 ret = install_thread_keyring();
539 if (ret < 0) {
540 key_ref = ERR_PTR(ret);
541 goto error;
542 }
543 goto reget_creds;
544 }
545
551 key = cred->thread_keyring;
546 key = ctx.cred->thread_keyring;
552 atomic_inc(&key->usage);
553 key_ref = make_key_ref(key, 1);
554 break;
555
556 case KEY_SPEC_PROCESS_KEYRING:
547 atomic_inc(&key->usage);
548 key_ref = make_key_ref(key, 1);
549 break;
550
551 case KEY_SPEC_PROCESS_KEYRING:
557 if (!cred->process_keyring) {
552 if (!ctx.cred->process_keyring) {
558 if (!(lflags & KEY_LOOKUP_CREATE))
559 goto error;
560
561 ret = install_process_keyring();
562 if (ret < 0) {
563 key_ref = ERR_PTR(ret);
564 goto error;
565 }
566 goto reget_creds;
567 }
568
553 if (!(lflags & KEY_LOOKUP_CREATE))
554 goto error;
555
556 ret = install_process_keyring();
557 if (ret < 0) {
558 key_ref = ERR_PTR(ret);
559 goto error;
560 }
561 goto reget_creds;
562 }
563
569 key = cred->process_keyring;
564 key = ctx.cred->process_keyring;
570 atomic_inc(&key->usage);
571 key_ref = make_key_ref(key, 1);
572 break;
573
574 case KEY_SPEC_SESSION_KEYRING:
565 atomic_inc(&key->usage);
566 key_ref = make_key_ref(key, 1);
567 break;
568
569 case KEY_SPEC_SESSION_KEYRING:
575 if (!cred->session_keyring) {
570 if (!ctx.cred->session_keyring) {
576 /* always install a session keyring upon access if one
577 * doesn't exist yet */
578 ret = install_user_keyrings();
579 if (ret < 0)
580 goto error;
581 if (lflags & KEY_LOOKUP_CREATE)
582 ret = join_session_keyring(NULL);
583 else
584 ret = install_session_keyring(
571 /* always install a session keyring upon access if one
572 * doesn't exist yet */
573 ret = install_user_keyrings();
574 if (ret < 0)
575 goto error;
576 if (lflags & KEY_LOOKUP_CREATE)
577 ret = join_session_keyring(NULL);
578 else
579 ret = install_session_keyring(
585 cred->user->session_keyring);
580 ctx.cred->user->session_keyring);
586
587 if (ret < 0)
588 goto error;
589 goto reget_creds;
581
582 if (ret < 0)
583 goto error;
584 goto reget_creds;
590 } else if (cred->session_keyring ==
591 cred->user->session_keyring &&
585 } else if (ctx.cred->session_keyring ==
586 ctx.cred->user->session_keyring &&
592 lflags & KEY_LOOKUP_CREATE) {
593 ret = join_session_keyring(NULL);
594 if (ret < 0)
595 goto error;
596 goto reget_creds;
597 }
598
599 rcu_read_lock();
587 lflags & KEY_LOOKUP_CREATE) {
588 ret = join_session_keyring(NULL);
589 if (ret < 0)
590 goto error;
591 goto reget_creds;
592 }
593
594 rcu_read_lock();
600 key = rcu_dereference(cred->session_keyring);
595 key = rcu_dereference(ctx.cred->session_keyring);
601 atomic_inc(&key->usage);
602 rcu_read_unlock();
603 key_ref = make_key_ref(key, 1);
604 break;
605
606 case KEY_SPEC_USER_KEYRING:
596 atomic_inc(&key->usage);
597 rcu_read_unlock();
598 key_ref = make_key_ref(key, 1);
599 break;
600
601 case KEY_SPEC_USER_KEYRING:
607 if (!cred->user->uid_keyring) {
602 if (!ctx.cred->user->uid_keyring) {
608 ret = install_user_keyrings();
609 if (ret < 0)
610 goto error;
611 }
612
603 ret = install_user_keyrings();
604 if (ret < 0)
605 goto error;
606 }
607
613 key = cred->user->uid_keyring;
608 key = ctx.cred->user->uid_keyring;
614 atomic_inc(&key->usage);
615 key_ref = make_key_ref(key, 1);
616 break;
617
618 case KEY_SPEC_USER_SESSION_KEYRING:
609 atomic_inc(&key->usage);
610 key_ref = make_key_ref(key, 1);
611 break;
612
613 case KEY_SPEC_USER_SESSION_KEYRING:
619 if (!cred->user->session_keyring) {
614 if (!ctx.cred->user->session_keyring) {
620 ret = install_user_keyrings();
621 if (ret < 0)
622 goto error;
623 }
624
615 ret = install_user_keyrings();
616 if (ret < 0)
617 goto error;
618 }
619
625 key = cred->user->session_keyring;
620 key = ctx.cred->user->session_keyring;
626 atomic_inc(&key->usage);
627 key_ref = make_key_ref(key, 1);
628 break;
629
630 case KEY_SPEC_GROUP_KEYRING:
631 /* group keyrings are not yet supported */
632 key_ref = ERR_PTR(-EINVAL);
633 goto error;
634
635 case KEY_SPEC_REQKEY_AUTH_KEY:
621 atomic_inc(&key->usage);
622 key_ref = make_key_ref(key, 1);
623 break;
624
625 case KEY_SPEC_GROUP_KEYRING:
626 /* group keyrings are not yet supported */
627 key_ref = ERR_PTR(-EINVAL);
628 goto error;
629
630 case KEY_SPEC_REQKEY_AUTH_KEY:
636 key = cred->request_key_auth;
631 key = ctx.cred->request_key_auth;
637 if (!key)
638 goto error;
639
640 atomic_inc(&key->usage);
641 key_ref = make_key_ref(key, 1);
642 break;
643
644 case KEY_SPEC_REQUESTOR_KEYRING:
632 if (!key)
633 goto error;
634
635 atomic_inc(&key->usage);
636 key_ref = make_key_ref(key, 1);
637 break;
638
639 case KEY_SPEC_REQUESTOR_KEYRING:
645 if (!cred->request_key_auth)
640 if (!ctx.cred->request_key_auth)
646 goto error;
647
641 goto error;
642
648 down_read(&cred->request_key_auth->sem);
643 down_read(&ctx.cred->request_key_auth->sem);
649 if (test_bit(KEY_FLAG_REVOKED,
644 if (test_bit(KEY_FLAG_REVOKED,
650 &cred->request_key_auth->flags)) {
645 &ctx.cred->request_key_auth->flags)) {
651 key_ref = ERR_PTR(-EKEYREVOKED);
652 key = NULL;
653 } else {
646 key_ref = ERR_PTR(-EKEYREVOKED);
647 key = NULL;
648 } else {
654 rka = cred->request_key_auth->payload.data;
649 rka = ctx.cred->request_key_auth->payload.data;
655 key = rka->dest_keyring;
656 atomic_inc(&key->usage);
657 }
650 key = rka->dest_keyring;
651 atomic_inc(&key->usage);
652 }
658 up_read(&cred->request_key_auth->sem);
653 up_read(&ctx.cred->request_key_auth->sem);
659 if (!key)
660 goto error;
661 key_ref = make_key_ref(key, 1);
662 break;
663
664 default:
665 key_ref = ERR_PTR(-EINVAL);
666 if (id < 1)
667 goto error;
668
669 key = key_lookup(id);
670 if (IS_ERR(key)) {
671 key_ref = ERR_CAST(key);
672 goto error;
673 }
674
675 key_ref = make_key_ref(key, 0);
676
677 /* check to see if we possess the key */
654 if (!key)
655 goto error;
656 key_ref = make_key_ref(key, 1);
657 break;
658
659 default:
660 key_ref = ERR_PTR(-EINVAL);
661 if (id < 1)
662 goto error;
663
664 key = key_lookup(id);
665 if (IS_ERR(key)) {
666 key_ref = ERR_CAST(key);
667 goto error;
668 }
669
670 key_ref = make_key_ref(key, 0);
671
672 /* check to see if we possess the key */
678 skey_ref = search_process_keyrings(key->type, key,
679 lookup_user_key_possessed,
680 true, cred);
673 ctx.index_key.type = key->type;
674 ctx.index_key.description = key->description;
675 ctx.index_key.desc_len = strlen(key->description);
676 ctx.match_data = key;
677 kdebug("check possessed");
678 skey_ref = search_process_keyrings(&ctx);
679 kdebug("possessed=%p", skey_ref);
681
682 if (!IS_ERR(skey_ref)) {
683 key_put(key);
684 key_ref = skey_ref;
685 }
686
687 break;
688 }

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

712 }
713
714 ret = -EIO;
715 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
716 !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
717 goto invalid_key;
718
719 /* check the permissions */
680
681 if (!IS_ERR(skey_ref)) {
682 key_put(key);
683 key_ref = skey_ref;
684 }
685
686 break;
687 }

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

711 }
712
713 ret = -EIO;
714 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
715 !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
716 goto invalid_key;
717
718 /* check the permissions */
720 ret = key_task_permission(key_ref, cred, perm);
719 ret = key_task_permission(key_ref, ctx.cred, perm);
721 if (ret < 0)
722 goto invalid_key;
723
724 key->last_used_at = current_kernel_time().tv_sec;
725
726error:
720 if (ret < 0)
721 goto invalid_key;
722
723 key->last_used_at = current_kernel_time().tv_sec;
724
725error:
727 put_cred(cred);
726 put_cred(ctx.cred);
728 return key_ref;
729
730invalid_key:
731 key_ref_put(key_ref);
732 key_ref = ERR_PTR(ret);
733 goto error;
734
735 /* if we attempted to install a keyring, then it may have caused new
736 * creds to be installed */
737reget_creds:
727 return key_ref;
728
729invalid_key:
730 key_ref_put(key_ref);
731 key_ref = ERR_PTR(ret);
732 goto error;
733
734 /* if we attempted to install a keyring, then it may have caused new
735 * creds to be installed */
736reget_creds:
738 put_cred(cred);
737 put_cred(ctx.cred);
739 goto try_again;
740}
741
742/*
743 * Join the named keyring as the session keyring if possible else attempt to
744 * create a new one of that name and join that.
745 *
746 * If the name is NULL, an empty anonymous keyring will be installed as the

--- 114 unchanged lines hidden ---
738 goto try_again;
739}
740
741/*
742 * Join the named keyring as the session keyring if possible else attempt to
743 * create a new one of that name and join that.
744 *
745 * If the name is NULL, an empty anonymous keyring will be installed as the

--- 114 unchanged lines hidden ---