diff options
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r-- | security/keys/process_keys.c | 88 |
1 files changed, 54 insertions, 34 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 5be6d018759a..1c793b7090a7 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -40,9 +40,9 @@ struct key_user root_key_user = { | |||
40 | /* | 40 | /* |
41 | * install user and user session keyrings for a particular UID | 41 | * install user and user session keyrings for a particular UID |
42 | */ | 42 | */ |
43 | static int install_user_keyrings(struct task_struct *tsk) | 43 | int install_user_keyrings(void) |
44 | { | 44 | { |
45 | struct user_struct *user = tsk->user; | 45 | struct user_struct *user = current->user; |
46 | struct key *uid_keyring, *session_keyring; | 46 | struct key *uid_keyring, *session_keyring; |
47 | char buf[20]; | 47 | char buf[20]; |
48 | int ret; | 48 | int ret; |
@@ -67,7 +67,7 @@ static int install_user_keyrings(struct task_struct *tsk) | |||
67 | uid_keyring = find_keyring_by_name(buf, true); | 67 | uid_keyring = find_keyring_by_name(buf, true); |
68 | if (IS_ERR(uid_keyring)) { | 68 | if (IS_ERR(uid_keyring)) { |
69 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, | 69 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, |
70 | tsk, KEY_ALLOC_IN_QUOTA, | 70 | current, KEY_ALLOC_IN_QUOTA, |
71 | NULL); | 71 | NULL); |
72 | if (IS_ERR(uid_keyring)) { | 72 | if (IS_ERR(uid_keyring)) { |
73 | ret = PTR_ERR(uid_keyring); | 73 | ret = PTR_ERR(uid_keyring); |
@@ -83,7 +83,8 @@ static int install_user_keyrings(struct task_struct *tsk) | |||
83 | if (IS_ERR(session_keyring)) { | 83 | if (IS_ERR(session_keyring)) { |
84 | session_keyring = | 84 | session_keyring = |
85 | keyring_alloc(buf, user->uid, (gid_t) -1, | 85 | keyring_alloc(buf, user->uid, (gid_t) -1, |
86 | tsk, KEY_ALLOC_IN_QUOTA, NULL); | 86 | current, KEY_ALLOC_IN_QUOTA, |
87 | NULL); | ||
87 | if (IS_ERR(session_keyring)) { | 88 | if (IS_ERR(session_keyring)) { |
88 | ret = PTR_ERR(session_keyring); | 89 | ret = PTR_ERR(session_keyring); |
89 | goto error_release; | 90 | goto error_release; |
@@ -146,8 +147,9 @@ void switch_uid_keyring(struct user_struct *new_user) | |||
146 | /* | 147 | /* |
147 | * install a fresh thread keyring, discarding the old one | 148 | * install a fresh thread keyring, discarding the old one |
148 | */ | 149 | */ |
149 | int install_thread_keyring(struct task_struct *tsk) | 150 | int install_thread_keyring(void) |
150 | { | 151 | { |
152 | struct task_struct *tsk = current; | ||
151 | struct key *keyring, *old; | 153 | struct key *keyring, *old; |
152 | char buf[20]; | 154 | char buf[20]; |
153 | int ret; | 155 | int ret; |
@@ -178,8 +180,9 @@ error: | |||
178 | /* | 180 | /* |
179 | * make sure a process keyring is installed | 181 | * make sure a process keyring is installed |
180 | */ | 182 | */ |
181 | int install_process_keyring(struct task_struct *tsk) | 183 | int install_process_keyring(void) |
182 | { | 184 | { |
185 | struct task_struct *tsk = current; | ||
183 | struct key *keyring; | 186 | struct key *keyring; |
184 | char buf[20]; | 187 | char buf[20]; |
185 | int ret; | 188 | int ret; |
@@ -218,9 +221,9 @@ error: | |||
218 | * install a session keyring, discarding the old one | 221 | * install a session keyring, discarding the old one |
219 | * - if a keyring is not supplied, an empty one is invented | 222 | * - if a keyring is not supplied, an empty one is invented |
220 | */ | 223 | */ |
221 | static int install_session_keyring(struct task_struct *tsk, | 224 | static int install_session_keyring(struct key *keyring) |
222 | struct key *keyring) | ||
223 | { | 225 | { |
226 | struct task_struct *tsk = current; | ||
224 | unsigned long flags; | 227 | unsigned long flags; |
225 | struct key *old; | 228 | struct key *old; |
226 | char buf[20]; | 229 | char buf[20]; |
@@ -572,93 +575,91 @@ static int lookup_user_key_possessed(const struct key *key, const void *target) | |||
572 | * - don't create special keyrings unless so requested | 575 | * - don't create special keyrings unless so requested |
573 | * - partially constructed keys aren't found unless requested | 576 | * - partially constructed keys aren't found unless requested |
574 | */ | 577 | */ |
575 | key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | 578 | key_ref_t lookup_user_key(key_serial_t id, int create, int partial, |
576 | int create, int partial, key_perm_t perm) | 579 | key_perm_t perm) |
577 | { | 580 | { |
581 | struct request_key_auth *rka; | ||
582 | struct task_struct *t = current; | ||
578 | key_ref_t key_ref, skey_ref; | 583 | key_ref_t key_ref, skey_ref; |
579 | struct key *key; | 584 | struct key *key; |
580 | int ret; | 585 | int ret; |
581 | 586 | ||
582 | if (!context) | ||
583 | context = current; | ||
584 | |||
585 | key_ref = ERR_PTR(-ENOKEY); | 587 | key_ref = ERR_PTR(-ENOKEY); |
586 | 588 | ||
587 | switch (id) { | 589 | switch (id) { |
588 | case KEY_SPEC_THREAD_KEYRING: | 590 | case KEY_SPEC_THREAD_KEYRING: |
589 | if (!context->thread_keyring) { | 591 | if (!t->thread_keyring) { |
590 | if (!create) | 592 | if (!create) |
591 | goto error; | 593 | goto error; |
592 | 594 | ||
593 | ret = install_thread_keyring(context); | 595 | ret = install_thread_keyring(); |
594 | if (ret < 0) { | 596 | if (ret < 0) { |
595 | key = ERR_PTR(ret); | 597 | key = ERR_PTR(ret); |
596 | goto error; | 598 | goto error; |
597 | } | 599 | } |
598 | } | 600 | } |
599 | 601 | ||
600 | key = context->thread_keyring; | 602 | key = t->thread_keyring; |
601 | atomic_inc(&key->usage); | 603 | atomic_inc(&key->usage); |
602 | key_ref = make_key_ref(key, 1); | 604 | key_ref = make_key_ref(key, 1); |
603 | break; | 605 | break; |
604 | 606 | ||
605 | case KEY_SPEC_PROCESS_KEYRING: | 607 | case KEY_SPEC_PROCESS_KEYRING: |
606 | if (!context->signal->process_keyring) { | 608 | if (!t->signal->process_keyring) { |
607 | if (!create) | 609 | if (!create) |
608 | goto error; | 610 | goto error; |
609 | 611 | ||
610 | ret = install_process_keyring(context); | 612 | ret = install_process_keyring(); |
611 | if (ret < 0) { | 613 | if (ret < 0) { |
612 | key = ERR_PTR(ret); | 614 | key = ERR_PTR(ret); |
613 | goto error; | 615 | goto error; |
614 | } | 616 | } |
615 | } | 617 | } |
616 | 618 | ||
617 | key = context->signal->process_keyring; | 619 | key = t->signal->process_keyring; |
618 | atomic_inc(&key->usage); | 620 | atomic_inc(&key->usage); |
619 | key_ref = make_key_ref(key, 1); | 621 | key_ref = make_key_ref(key, 1); |
620 | break; | 622 | break; |
621 | 623 | ||
622 | case KEY_SPEC_SESSION_KEYRING: | 624 | case KEY_SPEC_SESSION_KEYRING: |
623 | if (!context->signal->session_keyring) { | 625 | if (!t->signal->session_keyring) { |
624 | /* always install a session keyring upon access if one | 626 | /* always install a session keyring upon access if one |
625 | * doesn't exist yet */ | 627 | * doesn't exist yet */ |
626 | ret = install_user_keyrings(context); | 628 | ret = install_user_keyrings(); |
627 | if (ret < 0) | 629 | if (ret < 0) |
628 | goto error; | 630 | goto error; |
629 | ret = install_session_keyring( | 631 | ret = install_session_keyring(t->user->session_keyring); |
630 | context, context->user->session_keyring); | ||
631 | if (ret < 0) | 632 | if (ret < 0) |
632 | goto error; | 633 | goto error; |
633 | } | 634 | } |
634 | 635 | ||
635 | rcu_read_lock(); | 636 | rcu_read_lock(); |
636 | key = rcu_dereference(context->signal->session_keyring); | 637 | key = rcu_dereference(t->signal->session_keyring); |
637 | atomic_inc(&key->usage); | 638 | atomic_inc(&key->usage); |
638 | rcu_read_unlock(); | 639 | rcu_read_unlock(); |
639 | key_ref = make_key_ref(key, 1); | 640 | key_ref = make_key_ref(key, 1); |
640 | break; | 641 | break; |
641 | 642 | ||
642 | case KEY_SPEC_USER_KEYRING: | 643 | case KEY_SPEC_USER_KEYRING: |
643 | if (!context->user->uid_keyring) { | 644 | if (!t->user->uid_keyring) { |
644 | ret = install_user_keyrings(context); | 645 | ret = install_user_keyrings(); |
645 | if (ret < 0) | 646 | if (ret < 0) |
646 | goto error; | 647 | goto error; |
647 | } | 648 | } |
648 | 649 | ||
649 | key = context->user->uid_keyring; | 650 | key = t->user->uid_keyring; |
650 | atomic_inc(&key->usage); | 651 | atomic_inc(&key->usage); |
651 | key_ref = make_key_ref(key, 1); | 652 | key_ref = make_key_ref(key, 1); |
652 | break; | 653 | break; |
653 | 654 | ||
654 | case KEY_SPEC_USER_SESSION_KEYRING: | 655 | case KEY_SPEC_USER_SESSION_KEYRING: |
655 | if (!context->user->session_keyring) { | 656 | if (!t->user->session_keyring) { |
656 | ret = install_user_keyrings(context); | 657 | ret = install_user_keyrings(); |
657 | if (ret < 0) | 658 | if (ret < 0) |
658 | goto error; | 659 | goto error; |
659 | } | 660 | } |
660 | 661 | ||
661 | key = context->user->session_keyring; | 662 | key = t->user->session_keyring; |
662 | atomic_inc(&key->usage); | 663 | atomic_inc(&key->usage); |
663 | key_ref = make_key_ref(key, 1); | 664 | key_ref = make_key_ref(key, 1); |
664 | break; | 665 | break; |
@@ -669,7 +670,7 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
669 | goto error; | 670 | goto error; |
670 | 671 | ||
671 | case KEY_SPEC_REQKEY_AUTH_KEY: | 672 | case KEY_SPEC_REQKEY_AUTH_KEY: |
672 | key = context->request_key_auth; | 673 | key = t->request_key_auth; |
673 | if (!key) | 674 | if (!key) |
674 | goto error; | 675 | goto error; |
675 | 676 | ||
@@ -677,6 +678,25 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
677 | key_ref = make_key_ref(key, 1); | 678 | key_ref = make_key_ref(key, 1); |
678 | break; | 679 | break; |
679 | 680 | ||
681 | case KEY_SPEC_REQUESTOR_KEYRING: | ||
682 | if (!t->request_key_auth) | ||
683 | goto error; | ||
684 | |||
685 | down_read(&t->request_key_auth->sem); | ||
686 | if (t->request_key_auth->flags & KEY_FLAG_REVOKED) { | ||
687 | key_ref = ERR_PTR(-EKEYREVOKED); | ||
688 | key = NULL; | ||
689 | } else { | ||
690 | rka = t->request_key_auth->payload.data; | ||
691 | key = rka->dest_keyring; | ||
692 | atomic_inc(&key->usage); | ||
693 | } | ||
694 | up_read(&t->request_key_auth->sem); | ||
695 | if (!key) | ||
696 | goto error; | ||
697 | key_ref = make_key_ref(key, 1); | ||
698 | break; | ||
699 | |||
680 | default: | 700 | default: |
681 | key_ref = ERR_PTR(-EINVAL); | 701 | key_ref = ERR_PTR(-EINVAL); |
682 | if (id < 1) | 702 | if (id < 1) |
@@ -725,7 +745,7 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
725 | goto invalid_key; | 745 | goto invalid_key; |
726 | 746 | ||
727 | /* check the permissions */ | 747 | /* check the permissions */ |
728 | ret = key_task_permission(key_ref, context, perm); | 748 | ret = key_task_permission(key_ref, t, perm); |
729 | if (ret < 0) | 749 | if (ret < 0) |
730 | goto invalid_key; | 750 | goto invalid_key; |
731 | 751 | ||
@@ -754,7 +774,7 @@ long join_session_keyring(const char *name) | |||
754 | 774 | ||
755 | /* if no name is provided, install an anonymous keyring */ | 775 | /* if no name is provided, install an anonymous keyring */ |
756 | if (!name) { | 776 | if (!name) { |
757 | ret = install_session_keyring(tsk, NULL); | 777 | ret = install_session_keyring(NULL); |
758 | if (ret < 0) | 778 | if (ret < 0) |
759 | goto error; | 779 | goto error; |
760 | 780 | ||
@@ -784,7 +804,7 @@ long join_session_keyring(const char *name) | |||
784 | } | 804 | } |
785 | 805 | ||
786 | /* we've got a keyring - now to install it */ | 806 | /* we've got a keyring - now to install it */ |
787 | ret = install_session_keyring(tsk, keyring); | 807 | ret = install_session_keyring(keyring); |
788 | if (ret < 0) | 808 | if (ret < 0) |
789 | goto error2; | 809 | goto error2; |
790 | 810 | ||