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