[PATCH] Keys: Add possessor permissions to keys [try #3]

The attached patch adds extra permission grants to keys for the possessor of a
key in addition to the owner, group and other permissions bits. This makes
SUID binaries easier to support without going as far as labelling keys and key
targets using the LSM facilities.

This patch adds a second "pointer type" to key structures (struct key_ref *)
that can have the bottom bit of the address set to indicate the possession of
a key. This is propagated through searches from the keyring to the discovered
key. It has been made a separate type so that the compiler can spot attempts
to dereference a potentially incorrect pointer.

The "possession" attribute can't be attached to a key structure directly as
it's not an intrinsic property of a key.

Pointers to keys have been replaced with struct key_ref *'s wherever
possession information needs to be passed through.

This does assume that the bottom bit of the pointer will always be zero on
return from kmem_cache_alloc().

The key reference type has been made into a typedef so that at least it can be
located in the sources, even though it's basically a pointer to an undefined
type. I've also renamed the accessor functions to be more useful, and all
reference variables should now end in "_ref".

Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by David Howells and committed by Linus Torvalds 664cceb0 5134fc15

+526 -348
+55 -19
Documentation/keys.txt
··· 195 195 ====================== 196 196 197 197 Keys have an owner user ID, a group access ID, and a permissions mask. The mask 198 - has up to eight bits each for user, group and other access. Only five of each 199 - set of eight bits are defined. These permissions granted are: 198 + has up to eight bits each for possessor, user, group and other access. Only 199 + five of each set of eight bits are defined. These permissions granted are: 200 200 201 201 (*) View 202 202 ··· 241 241 type, description and permissions. The payload of the key is not available 242 242 this way: 243 243 244 - SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY 245 - 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4 246 - 00000002 I----- 2 perm 1f0000 0 0 keyring _uid.0: empty 247 - 00000007 I----- 1 perm 1f0000 0 0 keyring _pid.1: empty 248 - 0000018d I----- 1 perm 1f0000 0 0 keyring _pid.412: empty 249 - 000004d2 I--Q-- 1 perm 1f0000 32 -1 keyring _uid.32: 1/4 250 - 000004d3 I--Q-- 3 perm 1f0000 32 -1 keyring _uid_ses.32: empty 251 - 00000892 I--QU- 1 perm 1f0000 0 0 user metal:copper: 0 252 - 00000893 I--Q-N 1 35s 1f0000 0 0 user metal:silver: 0 253 - 00000894 I--Q-- 1 10h 1f0000 0 0 user metal:gold: 0 244 + SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY 245 + 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4 246 + 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty 247 + 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty 248 + 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty 249 + 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4 250 + 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty 251 + 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0 252 + 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0 253 + 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0 254 254 255 255 The flags are: 256 256 ··· 637 637 two different users opening the same file is left to the filesystem author to 638 638 solve. 639 639 640 + Note that there are two different types of pointers to keys that may be 641 + encountered: 642 + 643 + (*) struct key * 644 + 645 + This simply points to the key structure itself. Key structures will be at 646 + least four-byte aligned. 647 + 648 + (*) key_ref_t 649 + 650 + This is equivalent to a struct key *, but the least significant bit is set 651 + if the caller "possesses" the key. By "possession" it is meant that the 652 + calling processes has a searchable link to the key from one of its 653 + keyrings. There are three functions for dealing with these: 654 + 655 + key_ref_t make_key_ref(const struct key *key, 656 + unsigned long possession); 657 + 658 + struct key *key_ref_to_ptr(const key_ref_t key_ref); 659 + 660 + unsigned long is_key_possessed(const key_ref_t key_ref); 661 + 662 + The first function constructs a key reference from a key pointer and 663 + possession information (which must be 0 or 1 and not any other value). 664 + 665 + The second function retrieves the key pointer from a reference and the 666 + third retrieves the possession flag. 667 + 640 668 When accessing a key's payload contents, certain precautions must be taken to 641 669 prevent access vs modification races. See the section "Notes on accessing 642 670 payload contents" for more information. ··· 693 665 694 666 void key_put(struct key *key); 695 667 696 - This can be called from interrupt context. If CONFIG_KEYS is not set then 668 + Or: 669 + 670 + void key_ref_put(key_ref_t key_ref); 671 + 672 + These can be called from interrupt context. If CONFIG_KEYS is not set then 697 673 the argument will not be parsed. 698 674 699 675 ··· 721 689 722 690 (*) If a keyring was found in the search, this can be further searched by: 723 691 724 - struct key *keyring_search(struct key *keyring, 725 - const struct key_type *type, 726 - const char *description) 692 + key_ref_t keyring_search(key_ref_t keyring_ref, 693 + const struct key_type *type, 694 + const char *description) 727 695 728 696 This searches the keyring tree specified for a matching key. Error ENOKEY 729 - is returned upon failure. If successful, the returned key will need to be 730 - released. 697 + is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, 698 + the returned key will need to be released. 699 + 700 + The possession attribute from the keyring reference is used to control 701 + access through the permissions mask and is propagated to the returned key 702 + reference pointer if successful. 731 703 732 704 733 705 (*) To check the validity of a key, this function can be called: ··· 768 732 key->payload.data. One of the following ways must be selected to access the 769 733 data: 770 734 771 - (1) Unmodifyable key type. 735 + (1) Unmodifiable key type. 772 736 773 737 If the key type does not have a modify method, then the key's payload can 774 738 be accessed without any form of locking, provided that it's known to be
+19 -9
include/linux/key-ui.h
··· 42 42 /* 43 43 * check to see whether permission is granted to use a key in the desired way 44 44 */ 45 - static inline int key_permission(const struct key *key, key_perm_t perm) 45 + static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) 46 46 { 47 + struct key *key = key_ref_to_ptr(key_ref); 47 48 key_perm_t kperm; 48 49 49 - if (key->uid == current->fsuid) 50 + if (is_key_possessed(key_ref)) 51 + kperm = key->perm >> 24; 52 + else if (key->uid == current->fsuid) 50 53 kperm = key->perm >> 16; 51 54 else if (key->gid != -1 && 52 55 key->perm & KEY_GRP_ALL && ··· 68 65 * check to see whether permission is granted to use a key in at least one of 69 66 * the desired ways 70 67 */ 71 - static inline int key_any_permission(const struct key *key, key_perm_t perm) 68 + static inline int key_any_permission(const key_ref_t key_ref, key_perm_t perm) 72 69 { 70 + struct key *key = key_ref_to_ptr(key_ref); 73 71 key_perm_t kperm; 74 72 75 - if (key->uid == current->fsuid) 73 + if (is_key_possessed(key_ref)) 74 + kperm = key->perm >> 24; 75 + else if (key->uid == current->fsuid) 76 76 kperm = key->perm >> 16; 77 77 else if (key->gid != -1 && 78 78 key->perm & KEY_GRP_ALL && ··· 100 94 return ret; 101 95 } 102 96 103 - static inline int key_task_permission(const struct key *key, 97 + static inline int key_task_permission(const key_ref_t key_ref, 104 98 struct task_struct *context, 105 99 key_perm_t perm) 106 100 { 101 + struct key *key = key_ref_to_ptr(key_ref); 107 102 key_perm_t kperm; 108 103 109 - if (key->uid == context->fsuid) { 104 + if (is_key_possessed(key_ref)) { 105 + kperm = key->perm >> 24; 106 + } 107 + else if (key->uid == context->fsuid) { 110 108 kperm = key->perm >> 16; 111 109 } 112 110 else if (key->gid != -1 && ··· 131 121 132 122 } 133 123 134 - extern struct key *lookup_user_key(struct task_struct *context, 135 - key_serial_t id, int create, int partial, 136 - key_perm_t perm); 124 + extern key_ref_t lookup_user_key(struct task_struct *context, 125 + key_serial_t id, int create, int partial, 126 + key_perm_t perm); 137 127 138 128 extern long join_session_keyring(const char *name); 139 129
+63 -15
include/linux/key.h
··· 35 35 36 36 #undef KEY_DEBUGGING 37 37 38 - #define KEY_USR_VIEW 0x00010000 /* user can view a key's attributes */ 39 - #define KEY_USR_READ 0x00020000 /* user can read key payload / view keyring */ 40 - #define KEY_USR_WRITE 0x00040000 /* user can update key payload / add link to keyring */ 41 - #define KEY_USR_SEARCH 0x00080000 /* user can find a key in search / search a keyring */ 42 - #define KEY_USR_LINK 0x00100000 /* user can create a link to a key/keyring */ 38 + #define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */ 39 + #define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */ 40 + #define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */ 41 + #define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */ 42 + #define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */ 43 + #define KEY_POS_ALL 0x1f000000 44 + 45 + #define KEY_USR_VIEW 0x00010000 /* user permissions... */ 46 + #define KEY_USR_READ 0x00020000 47 + #define KEY_USR_WRITE 0x00040000 48 + #define KEY_USR_SEARCH 0x00080000 49 + #define KEY_USR_LINK 0x00100000 43 50 #define KEY_USR_ALL 0x001f0000 44 51 45 52 #define KEY_GRP_VIEW 0x00000100 /* group permissions... */ ··· 71 64 struct key_owner; 72 65 struct keyring_list; 73 66 struct keyring_name; 67 + 68 + /*****************************************************************************/ 69 + /* 70 + * key reference with possession attribute handling 71 + * 72 + * NOTE! key_ref_t is a typedef'd pointer to a type that is not actually 73 + * defined. This is because we abuse the bottom bit of the reference to carry a 74 + * flag to indicate whether the calling process possesses that key in one of 75 + * its keyrings. 76 + * 77 + * the key_ref_t has been made a separate type so that the compiler can reject 78 + * attempts to dereference it without proper conversion. 79 + * 80 + * the three functions are used to assemble and disassemble references 81 + */ 82 + typedef struct __key_reference_with_attributes *key_ref_t; 83 + 84 + static inline key_ref_t make_key_ref(const struct key *key, 85 + unsigned long possession) 86 + { 87 + return (key_ref_t) ((unsigned long) key | possession); 88 + } 89 + 90 + static inline struct key *key_ref_to_ptr(const key_ref_t key_ref) 91 + { 92 + return (struct key *) ((unsigned long) key_ref & ~1UL); 93 + } 94 + 95 + static inline unsigned long is_key_possessed(const key_ref_t key_ref) 96 + { 97 + return (unsigned long) key_ref & 1UL; 98 + } 74 99 75 100 /*****************************************************************************/ 76 101 /* ··· 254 215 return key; 255 216 } 256 217 218 + static inline void key_ref_put(key_ref_t key_ref) 219 + { 220 + key_put(key_ref_to_ptr(key_ref)); 221 + } 222 + 257 223 extern struct key *request_key(struct key_type *type, 258 224 const char *description, 259 225 const char *callout_info); 260 226 261 227 extern int key_validate(struct key *key); 262 228 263 - extern struct key *key_create_or_update(struct key *keyring, 264 - const char *type, 265 - const char *description, 266 - const void *payload, 267 - size_t plen, 268 - int not_in_quota); 229 + extern key_ref_t key_create_or_update(key_ref_t keyring, 230 + const char *type, 231 + const char *description, 232 + const void *payload, 233 + size_t plen, 234 + int not_in_quota); 269 235 270 - extern int key_update(struct key *key, 236 + extern int key_update(key_ref_t key, 271 237 const void *payload, 272 238 size_t plen); 273 239 ··· 287 243 288 244 extern int keyring_clear(struct key *keyring); 289 245 290 - extern struct key *keyring_search(struct key *keyring, 291 - struct key_type *type, 292 - const char *description); 246 + extern key_ref_t keyring_search(key_ref_t keyring, 247 + struct key_type *type, 248 + const char *description); 293 249 294 250 extern int keyring_add_key(struct key *keyring, 295 251 struct key *key); ··· 329 285 #define key_serial(k) 0 330 286 #define key_get(k) ({ NULL; }) 331 287 #define key_put(k) do { } while(0) 288 + #define key_ref_put(k) do { } while(0) 289 + #define make_key_ref(k) ({ NULL; }) 290 + #define key_ref_to_ptr(k) ({ NULL; }) 291 + #define is_key_possessed(k) 0 332 292 #define alloc_uid_keyring(u) 0 333 293 #define switch_uid_keyring(u) do { } while(0) 334 294 #define __install_session_keyring(t, k) ({ NULL; })
+13 -13
security/keys/internal.h
··· 71 71 72 72 extern int __key_link(struct key *keyring, struct key *key); 73 73 74 - extern struct key *__keyring_search_one(struct key *keyring, 75 - const struct key_type *type, 76 - const char *description, 77 - key_perm_t perm); 74 + extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, 75 + const struct key_type *type, 76 + const char *description, 77 + key_perm_t perm); 78 78 79 79 extern struct key *keyring_search_instkey(struct key *keyring, 80 80 key_serial_t target_id); 81 81 82 82 typedef int (*key_match_func_t)(const struct key *, const void *); 83 83 84 - extern struct key *keyring_search_aux(struct key *keyring, 85 - struct task_struct *tsk, 86 - struct key_type *type, 87 - const void *description, 88 - key_match_func_t match); 84 + extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 85 + struct task_struct *tsk, 86 + struct key_type *type, 87 + const void *description, 88 + key_match_func_t match); 89 89 90 - extern struct key *search_process_keyrings(struct key_type *type, 91 - const void *description, 92 - key_match_func_t match, 93 - struct task_struct *tsk); 90 + extern key_ref_t search_process_keyrings(struct key_type *type, 91 + const void *description, 92 + key_match_func_t match, 93 + struct task_struct *tsk); 94 94 95 95 extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); 96 96
+45 -36
security/keys/key.c
··· 693 693 * - the key has an incremented refcount 694 694 * - we need to put the key if we get an error 695 695 */ 696 - static inline struct key *__key_update(struct key *key, const void *payload, 697 - size_t plen) 696 + static inline key_ref_t __key_update(key_ref_t key_ref, 697 + const void *payload, size_t plen) 698 698 { 699 + struct key *key = key_ref_to_ptr(key_ref); 699 700 int ret; 700 701 701 702 /* need write permission on the key to update it */ 702 703 ret = -EACCES; 703 - if (!key_permission(key, KEY_WRITE)) 704 + if (!key_permission(key_ref, KEY_WRITE)) 704 705 goto error; 705 706 706 707 ret = -EEXIST; ··· 720 719 721 720 if (ret < 0) 722 721 goto error; 723 - out: 724 - return key; 722 + out: 723 + return key_ref; 725 724 726 - error: 725 + error: 727 726 key_put(key); 728 - key = ERR_PTR(ret); 727 + key_ref = ERR_PTR(ret); 729 728 goto out; 730 729 731 730 } /* end __key_update() */ ··· 735 734 * search the specified keyring for a key of the same description; if one is 736 735 * found, update it, otherwise add a new one 737 736 */ 738 - struct key *key_create_or_update(struct key *keyring, 739 - const char *type, 740 - const char *description, 741 - const void *payload, 742 - size_t plen, 743 - int not_in_quota) 737 + key_ref_t key_create_or_update(key_ref_t keyring_ref, 738 + const char *type, 739 + const char *description, 740 + const void *payload, 741 + size_t plen, 742 + int not_in_quota) 744 743 { 745 744 struct key_type *ktype; 746 - struct key *key = NULL; 745 + struct key *keyring, *key = NULL; 747 746 key_perm_t perm; 747 + key_ref_t key_ref; 748 748 int ret; 749 - 750 - key_check(keyring); 751 749 752 750 /* look up the key type to see if it's one of the registered kernel 753 751 * types */ 754 752 ktype = key_type_lookup(type); 755 753 if (IS_ERR(ktype)) { 756 - key = ERR_PTR(-ENODEV); 754 + key_ref = ERR_PTR(-ENODEV); 757 755 goto error; 758 756 } 759 757 760 - ret = -EINVAL; 758 + key_ref = ERR_PTR(-EINVAL); 761 759 if (!ktype->match || !ktype->instantiate) 762 760 goto error_2; 761 + 762 + keyring = key_ref_to_ptr(keyring_ref); 763 + 764 + key_check(keyring); 765 + 766 + down_write(&keyring->sem); 767 + 768 + /* if we're going to allocate a new key, we're going to have 769 + * to modify the keyring */ 770 + key_ref = ERR_PTR(-EACCES); 771 + if (!key_permission(keyring_ref, KEY_WRITE)) 772 + goto error_3; 763 773 764 774 /* search for an existing key of the same type and description in the 765 775 * destination keyring 766 776 */ 767 - down_write(&keyring->sem); 768 - 769 - key = __keyring_search_one(keyring, ktype, description, 0); 770 - if (!IS_ERR(key)) 777 + key_ref = __keyring_search_one(keyring_ref, ktype, description, 0); 778 + if (!IS_ERR(key_ref)) 771 779 goto found_matching_key; 772 780 773 - /* if we're going to allocate a new key, we're going to have to modify 774 - * the keyring */ 775 - ret = -EACCES; 776 - if (!key_permission(keyring, KEY_WRITE)) 777 - goto error_3; 778 - 779 781 /* decide on the permissions we want */ 780 - perm = KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK; 782 + perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK; 783 + perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK; 781 784 782 785 if (ktype->read) 783 - perm |= KEY_USR_READ; 786 + perm |= KEY_POS_READ | KEY_USR_READ; 784 787 785 788 if (ktype == &key_type_keyring || ktype->update) 786 789 perm |= KEY_USR_WRITE; ··· 793 788 key = key_alloc(ktype, description, current->fsuid, current->fsgid, 794 789 perm, not_in_quota); 795 790 if (IS_ERR(key)) { 796 - ret = PTR_ERR(key); 791 + key_ref = ERR_PTR(PTR_ERR(key)); 797 792 goto error_3; 798 793 } 799 794 ··· 801 796 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL); 802 797 if (ret < 0) { 803 798 key_put(key); 804 - key = ERR_PTR(ret); 799 + key_ref = ERR_PTR(ret); 800 + goto error_3; 805 801 } 802 + 803 + key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 806 804 807 805 error_3: 808 806 up_write(&keyring->sem); 809 807 error_2: 810 808 key_type_put(ktype); 811 809 error: 812 - return key; 810 + return key_ref; 813 811 814 812 found_matching_key: 815 813 /* we found a matching key, so we're going to try to update it ··· 821 813 up_write(&keyring->sem); 822 814 key_type_put(ktype); 823 815 824 - key = __key_update(key, payload, plen); 816 + key_ref = __key_update(key_ref, payload, plen); 825 817 goto error; 826 818 827 819 } /* end key_create_or_update() */ ··· 832 824 /* 833 825 * update a key 834 826 */ 835 - int key_update(struct key *key, const void *payload, size_t plen) 827 + int key_update(key_ref_t key_ref, const void *payload, size_t plen) 836 828 { 829 + struct key *key = key_ref_to_ptr(key_ref); 837 830 int ret; 838 831 839 832 key_check(key); 840 833 841 834 /* the key must be writable */ 842 835 ret = -EACCES; 843 - if (!key_permission(key, KEY_WRITE)) 836 + if (!key_permission(key_ref, KEY_WRITE)) 844 837 goto error; 845 838 846 839 /* attempt to update it if supported */
+149 -148
security/keys/keyctl.c
··· 34 34 size_t plen, 35 35 key_serial_t ringid) 36 36 { 37 - struct key *keyring, *key; 37 + key_ref_t keyring_ref, key_ref; 38 38 char type[32], *description; 39 39 void *payload; 40 40 long dlen, ret; ··· 86 86 } 87 87 88 88 /* find the target keyring (which must be writable) */ 89 - keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 90 - if (IS_ERR(keyring)) { 91 - ret = PTR_ERR(keyring); 89 + keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 90 + if (IS_ERR(keyring_ref)) { 91 + ret = PTR_ERR(keyring_ref); 92 92 goto error3; 93 93 } 94 94 95 95 /* create or update the requested key and add it to the target 96 96 * keyring */ 97 - key = key_create_or_update(keyring, type, description, 98 - payload, plen, 0); 99 - if (!IS_ERR(key)) { 100 - ret = key->serial; 101 - key_put(key); 97 + key_ref = key_create_or_update(keyring_ref, type, description, 98 + payload, plen, 0); 99 + if (!IS_ERR(key_ref)) { 100 + ret = key_ref_to_ptr(key_ref)->serial; 101 + key_ref_put(key_ref); 102 102 } 103 103 else { 104 - ret = PTR_ERR(key); 104 + ret = PTR_ERR(key_ref); 105 105 } 106 106 107 - key_put(keyring); 107 + key_ref_put(keyring_ref); 108 108 error3: 109 109 kfree(payload); 110 110 error2: ··· 131 131 key_serial_t destringid) 132 132 { 133 133 struct key_type *ktype; 134 - struct key *key, *dest; 134 + struct key *key; 135 + key_ref_t dest_ref; 135 136 char type[32], *description, *callout_info; 136 137 long dlen, ret; 137 138 ··· 188 187 } 189 188 190 189 /* get the destination keyring if specified */ 191 - dest = NULL; 190 + dest_ref = NULL; 192 191 if (destringid) { 193 - dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 194 - if (IS_ERR(dest)) { 195 - ret = PTR_ERR(dest); 192 + dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 193 + if (IS_ERR(dest_ref)) { 194 + ret = PTR_ERR(dest_ref); 196 195 goto error3; 197 196 } 198 197 } ··· 205 204 } 206 205 207 206 /* do the search */ 208 - key = request_key_and_link(ktype, description, callout_info, dest); 207 + key = request_key_and_link(ktype, description, callout_info, 208 + key_ref_to_ptr(dest_ref)); 209 209 if (IS_ERR(key)) { 210 210 ret = PTR_ERR(key); 211 211 goto error5; ··· 218 216 error5: 219 217 key_type_put(ktype); 220 218 error4: 221 - key_put(dest); 219 + key_ref_put(dest_ref); 222 220 error3: 223 221 kfree(callout_info); 224 222 error2: ··· 236 234 */ 237 235 long keyctl_get_keyring_ID(key_serial_t id, int create) 238 236 { 239 - struct key *key; 237 + key_ref_t key_ref; 240 238 long ret; 241 239 242 - key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); 243 - if (IS_ERR(key)) { 244 - ret = PTR_ERR(key); 240 + key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); 241 + if (IS_ERR(key_ref)) { 242 + ret = PTR_ERR(key_ref); 245 243 goto error; 246 244 } 247 245 248 - ret = key->serial; 249 - key_put(key); 246 + ret = key_ref_to_ptr(key_ref)->serial; 247 + key_ref_put(key_ref); 250 248 error: 251 249 return ret; 252 250 ··· 304 302 const void __user *_payload, 305 303 size_t plen) 306 304 { 307 - struct key *key; 305 + key_ref_t key_ref; 308 306 void *payload; 309 307 long ret; 310 308 ··· 326 324 } 327 325 328 326 /* find the target key (which must be writable) */ 329 - key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 330 - if (IS_ERR(key)) { 331 - ret = PTR_ERR(key); 327 + key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 328 + if (IS_ERR(key_ref)) { 329 + ret = PTR_ERR(key_ref); 332 330 goto error2; 333 331 } 334 332 335 333 /* update the key */ 336 - ret = key_update(key, payload, plen); 334 + ret = key_update(key_ref, payload, plen); 337 335 338 - key_put(key); 336 + key_ref_put(key_ref); 339 337 error2: 340 338 kfree(payload); 341 339 error: ··· 351 349 */ 352 350 long keyctl_revoke_key(key_serial_t id) 353 351 { 354 - struct key *key; 352 + key_ref_t key_ref; 355 353 long ret; 356 354 357 - key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 358 - if (IS_ERR(key)) { 359 - ret = PTR_ERR(key); 355 + key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); 356 + if (IS_ERR(key_ref)) { 357 + ret = PTR_ERR(key_ref); 360 358 goto error; 361 359 } 362 360 363 - key_revoke(key); 361 + key_revoke(key_ref_to_ptr(key_ref)); 364 362 ret = 0; 365 363 366 - key_put(key); 364 + key_ref_put(key_ref); 367 365 error: 368 366 return ret; 369 367 ··· 377 375 */ 378 376 long keyctl_keyring_clear(key_serial_t ringid) 379 377 { 380 - struct key *keyring; 378 + key_ref_t keyring_ref; 381 379 long ret; 382 380 383 - keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 384 - if (IS_ERR(keyring)) { 385 - ret = PTR_ERR(keyring); 381 + keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 382 + if (IS_ERR(keyring_ref)) { 383 + ret = PTR_ERR(keyring_ref); 386 384 goto error; 387 385 } 388 386 389 - ret = keyring_clear(keyring); 387 + ret = keyring_clear(key_ref_to_ptr(keyring_ref)); 390 388 391 - key_put(keyring); 389 + key_ref_put(keyring_ref); 392 390 error: 393 391 return ret; 394 392 ··· 403 401 */ 404 402 long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) 405 403 { 406 - struct key *keyring, *key; 404 + key_ref_t keyring_ref, key_ref; 407 405 long ret; 408 406 409 - keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 410 - if (IS_ERR(keyring)) { 411 - ret = PTR_ERR(keyring); 407 + keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 408 + if (IS_ERR(keyring_ref)) { 409 + ret = PTR_ERR(keyring_ref); 412 410 goto error; 413 411 } 414 412 415 - key = lookup_user_key(NULL, id, 1, 0, KEY_LINK); 416 - if (IS_ERR(key)) { 417 - ret = PTR_ERR(key); 413 + key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK); 414 + if (IS_ERR(key_ref)) { 415 + ret = PTR_ERR(key_ref); 418 416 goto error2; 419 417 } 420 418 421 - ret = key_link(keyring, key); 419 + ret = key_link(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref)); 422 420 423 - key_put(key); 421 + key_ref_put(key_ref); 424 422 error2: 425 - key_put(keyring); 423 + key_ref_put(keyring_ref); 426 424 error: 427 425 return ret; 428 426 ··· 437 435 */ 438 436 long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) 439 437 { 440 - struct key *keyring, *key; 438 + key_ref_t keyring_ref, key_ref; 441 439 long ret; 442 440 443 - keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); 444 - if (IS_ERR(keyring)) { 445 - ret = PTR_ERR(keyring); 441 + keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); 442 + if (IS_ERR(keyring_ref)) { 443 + ret = PTR_ERR(keyring_ref); 446 444 goto error; 447 445 } 448 446 449 - key = lookup_user_key(NULL, id, 0, 0, 0); 450 - if (IS_ERR(key)) { 451 - ret = PTR_ERR(key); 447 + key_ref = lookup_user_key(NULL, id, 0, 0, 0); 448 + if (IS_ERR(key_ref)) { 449 + ret = PTR_ERR(key_ref); 452 450 goto error2; 453 451 } 454 452 455 - ret = key_unlink(keyring, key); 453 + ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref)); 456 454 457 - key_put(key); 455 + key_ref_put(key_ref); 458 456 error2: 459 - key_put(keyring); 457 + key_ref_put(keyring_ref); 460 458 error: 461 459 return ret; 462 460 ··· 478 476 size_t buflen) 479 477 { 480 478 struct key *key, *instkey; 479 + key_ref_t key_ref; 481 480 char *tmpbuf; 482 481 long ret; 483 482 484 - key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); 485 - if (IS_ERR(key)) { 483 + key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); 484 + if (IS_ERR(key_ref)) { 486 485 /* viewing a key under construction is permitted if we have the 487 486 * authorisation token handy */ 488 - if (PTR_ERR(key) == -EACCES) { 487 + if (PTR_ERR(key_ref) == -EACCES) { 489 488 instkey = key_get_instantiation_authkey(keyid); 490 489 if (!IS_ERR(instkey)) { 491 490 key_put(instkey); 492 - key = lookup_user_key(NULL, keyid, 0, 1, 0); 493 - if (!IS_ERR(key)) 491 + key_ref = lookup_user_key(NULL, keyid, 492 + 0, 1, 0); 493 + if (!IS_ERR(key_ref)) 494 494 goto okay; 495 495 } 496 496 } 497 497 498 - ret = PTR_ERR(key); 498 + ret = PTR_ERR(key_ref); 499 499 goto error; 500 500 } 501 501 ··· 508 504 if (!tmpbuf) 509 505 goto error2; 510 506 507 + key = key_ref_to_ptr(key_ref); 508 + 511 509 ret = snprintf(tmpbuf, PAGE_SIZE - 1, 512 - "%s;%d;%d;%06x;%s", 513 - key->type->name, 514 - key->uid, 515 - key->gid, 516 - key->perm, 517 - key->description ? key->description :"" 510 + "%s;%d;%d;%08x;%s", 511 + key_ref_to_ptr(key_ref)->type->name, 512 + key_ref_to_ptr(key_ref)->uid, 513 + key_ref_to_ptr(key_ref)->gid, 514 + key_ref_to_ptr(key_ref)->perm, 515 + key_ref_to_ptr(key_ref)->description ? 516 + key_ref_to_ptr(key_ref)->description : "" 518 517 ); 519 518 520 519 /* include a NUL char at the end of the data */ ··· 537 530 538 531 kfree(tmpbuf); 539 532 error2: 540 - key_put(key); 533 + key_ref_put(key_ref); 541 534 error: 542 535 return ret; 543 536 ··· 559 552 key_serial_t destringid) 560 553 { 561 554 struct key_type *ktype; 562 - struct key *keyring, *key, *dest; 555 + key_ref_t keyring_ref, key_ref, dest_ref; 563 556 char type[32], *description; 564 557 long dlen, ret; 565 558 ··· 588 581 goto error2; 589 582 590 583 /* get the keyring at which to begin the search */ 591 - keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); 592 - if (IS_ERR(keyring)) { 593 - ret = PTR_ERR(keyring); 584 + keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); 585 + if (IS_ERR(keyring_ref)) { 586 + ret = PTR_ERR(keyring_ref); 594 587 goto error2; 595 588 } 596 589 597 590 /* get the destination keyring if specified */ 598 - dest = NULL; 591 + dest_ref = NULL; 599 592 if (destringid) { 600 - dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 601 - if (IS_ERR(dest)) { 602 - ret = PTR_ERR(dest); 593 + dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); 594 + if (IS_ERR(dest_ref)) { 595 + ret = PTR_ERR(dest_ref); 603 596 goto error3; 604 597 } 605 598 } ··· 612 605 } 613 606 614 607 /* do the search */ 615 - key = keyring_search(keyring, ktype, description); 616 - if (IS_ERR(key)) { 617 - ret = PTR_ERR(key); 608 + key_ref = keyring_search(keyring_ref, ktype, description); 609 + if (IS_ERR(key_ref)) { 610 + ret = PTR_ERR(key_ref); 618 611 619 612 /* treat lack or presence of a negative key the same */ 620 613 if (ret == -EAGAIN) ··· 623 616 } 624 617 625 618 /* link the resulting key to the destination keyring if we can */ 626 - if (dest) { 619 + if (dest_ref) { 627 620 ret = -EACCES; 628 - if (!key_permission(key, KEY_LINK)) 621 + if (!key_permission(key_ref, KEY_LINK)) 629 622 goto error6; 630 623 631 - ret = key_link(dest, key); 624 + ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref)); 632 625 if (ret < 0) 633 626 goto error6; 634 627 } 635 628 636 - ret = key->serial; 629 + ret = key_ref_to_ptr(key_ref)->serial; 637 630 638 631 error6: 639 - key_put(key); 632 + key_ref_put(key_ref); 640 633 error5: 641 634 key_type_put(ktype); 642 635 error4: 643 - key_put(dest); 636 + key_ref_put(dest_ref); 644 637 error3: 645 - key_put(keyring); 638 + key_ref_put(keyring_ref); 646 639 error2: 647 640 kfree(description); 648 641 error: 649 642 return ret; 650 643 651 644 } /* end keyctl_keyring_search() */ 652 - 653 - /*****************************************************************************/ 654 - /* 655 - * see if the key we're looking at is the target key 656 - */ 657 - static int keyctl_read_key_same(const struct key *key, const void *target) 658 - { 659 - return key == target; 660 - 661 - } /* end keyctl_read_key_same() */ 662 645 663 646 /*****************************************************************************/ 664 647 /* ··· 662 665 */ 663 666 long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) 664 667 { 665 - struct key *key, *skey; 668 + struct key *key; 669 + key_ref_t key_ref; 666 670 long ret; 667 671 668 672 /* find the key first */ 669 - key = lookup_user_key(NULL, keyid, 0, 0, 0); 670 - if (!IS_ERR(key)) { 671 - /* see if we can read it directly */ 672 - if (key_permission(key, KEY_READ)) 673 - goto can_read_key; 673 + key_ref = lookup_user_key(NULL, keyid, 0, 0, 0); 674 + if (IS_ERR(key_ref)) { 675 + ret = -ENOKEY; 676 + goto error; 677 + } 674 678 675 - /* we can't; see if it's searchable from this process's 676 - * keyrings 677 - * - we automatically take account of the fact that it may be 678 - * dangling off an instantiation key 679 - */ 680 - skey = search_process_keyrings(key->type, key, 681 - keyctl_read_key_same, current); 682 - if (!IS_ERR(skey)) 683 - goto can_read_key2; 679 + key = key_ref_to_ptr(key_ref); 684 680 685 - ret = PTR_ERR(skey); 686 - if (ret == -EAGAIN) 687 - ret = -EACCES; 681 + /* see if we can read it directly */ 682 + if (key_permission(key_ref, KEY_READ)) 683 + goto can_read_key; 684 + 685 + /* we can't; see if it's searchable from this process's keyrings 686 + * - we automatically take account of the fact that it may be 687 + * dangling off an instantiation key 688 + */ 689 + if (!is_key_possessed(key_ref)) { 690 + ret = -EACCES; 688 691 goto error2; 689 692 } 690 693 691 - ret = -ENOKEY; 692 - goto error; 693 - 694 694 /* the key is probably readable - now try to read it */ 695 - can_read_key2: 696 - key_put(skey); 697 695 can_read_key: 698 696 ret = key_validate(key); 699 697 if (ret == 0) { ··· 719 727 long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) 720 728 { 721 729 struct key *key; 730 + key_ref_t key_ref; 722 731 long ret; 723 732 724 733 ret = 0; 725 734 if (uid == (uid_t) -1 && gid == (gid_t) -1) 726 735 goto error; 727 736 728 - key = lookup_user_key(NULL, id, 1, 1, 0); 729 - if (IS_ERR(key)) { 730 - ret = PTR_ERR(key); 737 + key_ref = lookup_user_key(NULL, id, 1, 1, 0); 738 + if (IS_ERR(key_ref)) { 739 + ret = PTR_ERR(key_ref); 731 740 goto error; 732 741 } 742 + 743 + key = key_ref_to_ptr(key_ref); 733 744 734 745 /* make the changes with the locks held to prevent chown/chown races */ 735 746 ret = -EACCES; ··· 779 784 long keyctl_setperm_key(key_serial_t id, key_perm_t perm) 780 785 { 781 786 struct key *key; 787 + key_ref_t key_ref; 782 788 long ret; 783 789 784 790 ret = -EINVAL; 785 - if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 791 + if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 786 792 goto error; 787 793 788 - key = lookup_user_key(NULL, id, 1, 1, 0); 789 - if (IS_ERR(key)) { 790 - ret = PTR_ERR(key); 794 + key_ref = lookup_user_key(NULL, id, 1, 1, 0); 795 + if (IS_ERR(key_ref)) { 796 + ret = PTR_ERR(key_ref); 791 797 goto error; 792 798 } 799 + 800 + key = key_ref_to_ptr(key_ref); 793 801 794 802 /* make the changes with the locks held to prevent chown/chmod races */ 795 803 ret = -EACCES; ··· 822 824 key_serial_t ringid) 823 825 { 824 826 struct request_key_auth *rka; 825 - struct key *instkey, *keyring; 827 + struct key *instkey; 828 + key_ref_t keyring_ref; 826 829 void *payload; 827 830 long ret; 828 831 ··· 856 857 857 858 /* find the destination keyring amongst those belonging to the 858 859 * requesting task */ 859 - keyring = NULL; 860 + keyring_ref = NULL; 860 861 if (ringid) { 861 - keyring = lookup_user_key(rka->context, ringid, 1, 0, 862 - KEY_WRITE); 863 - if (IS_ERR(keyring)) { 864 - ret = PTR_ERR(keyring); 862 + keyring_ref = lookup_user_key(rka->context, ringid, 1, 0, 863 + KEY_WRITE); 864 + if (IS_ERR(keyring_ref)) { 865 + ret = PTR_ERR(keyring_ref); 865 866 goto error3; 866 867 } 867 868 } 868 869 869 870 /* instantiate the key and link it into a keyring */ 870 871 ret = key_instantiate_and_link(rka->target_key, payload, plen, 871 - keyring, instkey); 872 + key_ref_to_ptr(keyring_ref), instkey); 872 873 873 - key_put(keyring); 874 + key_ref_put(keyring_ref); 874 875 error3: 875 876 key_put(instkey); 876 877 error2: ··· 888 889 long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 889 890 { 890 891 struct request_key_auth *rka; 891 - struct key *instkey, *keyring; 892 + struct key *instkey; 893 + key_ref_t keyring_ref; 892 894 long ret; 893 895 894 896 /* find the instantiation authorisation key */ ··· 903 903 904 904 /* find the destination keyring if present (which must also be 905 905 * writable) */ 906 - keyring = NULL; 906 + keyring_ref = NULL; 907 907 if (ringid) { 908 - keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 909 - if (IS_ERR(keyring)) { 910 - ret = PTR_ERR(keyring); 908 + keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 909 + if (IS_ERR(keyring_ref)) { 910 + ret = PTR_ERR(keyring_ref); 911 911 goto error2; 912 912 } 913 913 } 914 914 915 915 /* instantiate the key and link it into a keyring */ 916 - ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey); 916 + ret = key_negate_and_link(rka->target_key, timeout, 917 + key_ref_to_ptr(keyring_ref), instkey); 917 918 918 - key_put(keyring); 919 + key_ref_put(keyring_ref); 919 920 error2: 920 921 key_put(instkey); 921 922 error:
+50 -36
security/keys/keyring.c
··· 309 309 int ret; 310 310 311 311 keyring = key_alloc(&key_type_keyring, description, 312 - uid, gid, KEY_USR_ALL, not_in_quota); 312 + uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota); 313 313 314 314 if (!IS_ERR(keyring)) { 315 315 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); ··· 333 333 * - we rely on RCU to prevent the keyring lists from disappearing on us 334 334 * - we return -EAGAIN if we didn't find any matching key 335 335 * - we return -ENOKEY if we only found negative matching keys 336 + * - we propagate the possession attribute from the keyring ref to the key ref 336 337 */ 337 - struct key *keyring_search_aux(struct key *keyring, 338 - struct task_struct *context, 339 - struct key_type *type, 340 - const void *description, 341 - key_match_func_t match) 338 + key_ref_t keyring_search_aux(key_ref_t keyring_ref, 339 + struct task_struct *context, 340 + struct key_type *type, 341 + const void *description, 342 + key_match_func_t match) 342 343 { 343 344 struct { 344 345 struct keyring_list *keylist; ··· 348 347 349 348 struct keyring_list *keylist; 350 349 struct timespec now; 351 - struct key *key; 350 + unsigned long possessed; 351 + struct key *keyring, *key; 352 + key_ref_t key_ref; 352 353 long err; 353 354 int sp, kix; 354 355 356 + keyring = key_ref_to_ptr(keyring_ref); 357 + possessed = is_key_possessed(keyring_ref); 355 358 key_check(keyring); 356 359 357 - rcu_read_lock(); 358 - 359 360 /* top keyring must have search permission to begin the search */ 360 - key = ERR_PTR(-EACCES); 361 - if (!key_task_permission(keyring, context, KEY_SEARCH)) 361 + key_ref = ERR_PTR(-EACCES); 362 + if (!key_task_permission(keyring_ref, context, KEY_SEARCH)) 362 363 goto error; 363 364 364 - key = ERR_PTR(-ENOTDIR); 365 + key_ref = ERR_PTR(-ENOTDIR); 365 366 if (keyring->type != &key_type_keyring) 366 367 goto error; 368 + 369 + rcu_read_lock(); 367 370 368 371 now = current_kernel_time(); 369 372 err = -EAGAIN; 370 373 sp = 0; 371 374 372 375 /* start processing a new keyring */ 373 - descend: 376 + descend: 374 377 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 375 378 goto not_this_keyring; 376 379 ··· 402 397 continue; 403 398 404 399 /* key must have search permissions */ 405 - if (!key_task_permission(key, context, KEY_SEARCH)) 400 + if (!key_task_permission(make_key_ref(key, possessed), 401 + context, KEY_SEARCH)) 406 402 continue; 407 403 408 404 /* we set a different error code if we find a negative key */ ··· 417 411 418 412 /* search through the keyrings nested in this one */ 419 413 kix = 0; 420 - ascend: 414 + ascend: 421 415 for (; kix < keylist->nkeys; kix++) { 422 416 key = keylist->keys[kix]; 423 417 if (key->type != &key_type_keyring) ··· 429 423 if (sp >= KEYRING_SEARCH_MAX_DEPTH) 430 424 continue; 431 425 432 - if (!key_task_permission(key, context, KEY_SEARCH)) 426 + if (!key_task_permission(make_key_ref(key, possessed), 427 + context, KEY_SEARCH)) 433 428 continue; 434 429 435 430 /* stack the current position */ ··· 445 438 446 439 /* the keyring we're looking at was disqualified or didn't contain a 447 440 * matching key */ 448 - not_this_keyring: 441 + not_this_keyring: 449 442 if (sp > 0) { 450 443 /* resume the processing of a keyring higher up in the tree */ 451 444 sp--; ··· 454 447 goto ascend; 455 448 } 456 449 457 - key = ERR_PTR(err); 458 - goto error; 450 + key_ref = ERR_PTR(err); 451 + goto error_2; 459 452 460 453 /* we found a viable match */ 461 - found: 454 + found: 462 455 atomic_inc(&key->usage); 463 456 key_check(key); 464 - error: 457 + key_ref = make_key_ref(key, possessed); 458 + error_2: 465 459 rcu_read_unlock(); 466 - return key; 460 + error: 461 + return key_ref; 467 462 468 463 } /* end keyring_search_aux() */ 469 464 ··· 478 469 * - we return -EAGAIN if we didn't find any matching key 479 470 * - we return -ENOKEY if we only found negative matching keys 480 471 */ 481 - struct key *keyring_search(struct key *keyring, 482 - struct key_type *type, 483 - const char *description) 472 + key_ref_t keyring_search(key_ref_t keyring, 473 + struct key_type *type, 474 + const char *description) 484 475 { 485 476 if (!type->match) 486 477 return ERR_PTR(-ENOKEY); ··· 497 488 * search the given keyring only (no recursion) 498 489 * - keyring must be locked by caller 499 490 */ 500 - struct key *__keyring_search_one(struct key *keyring, 501 - const struct key_type *ktype, 502 - const char *description, 503 - key_perm_t perm) 491 + key_ref_t __keyring_search_one(key_ref_t keyring_ref, 492 + const struct key_type *ktype, 493 + const char *description, 494 + key_perm_t perm) 504 495 { 505 496 struct keyring_list *klist; 506 - struct key *key; 497 + unsigned long possessed; 498 + struct key *keyring, *key; 507 499 int loop; 500 + 501 + keyring = key_ref_to_ptr(keyring_ref); 502 + possessed = is_key_possessed(keyring_ref); 508 503 509 504 rcu_read_lock(); 510 505 ··· 520 507 if (key->type == ktype && 521 508 (!key->type->match || 522 509 key->type->match(key, description)) && 523 - key_permission(key, perm) && 510 + key_permission(make_key_ref(key, possessed), 511 + perm) && 524 512 !test_bit(KEY_FLAG_REVOKED, &key->flags) 525 513 ) 526 514 goto found; 527 515 } 528 516 } 529 517 530 - key = ERR_PTR(-ENOKEY); 531 - goto error; 518 + rcu_read_unlock(); 519 + return ERR_PTR(-ENOKEY); 532 520 533 521 found: 534 522 atomic_inc(&key->usage); 535 - error: 536 523 rcu_read_unlock(); 537 - return key; 524 + return make_key_ref(key, possessed); 538 525 539 526 } /* end __keyring_search_one() */ 540 527 ··· 616 603 if (strcmp(keyring->description, name) != 0) 617 604 continue; 618 605 619 - if (!key_permission(keyring, KEY_SEARCH)) 606 + if (!key_permission(make_key_ref(keyring, 0), 607 + KEY_SEARCH)) 620 608 continue; 621 609 622 610 /* found a potential candidate, but we still need to
+1 -1
security/keys/proc.c
··· 167 167 #define showflag(KEY, LETTER, FLAG) \ 168 168 (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') 169 169 170 - seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ", 170 + seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", 171 171 key->serial, 172 172 showflag(key, 'I', KEY_FLAG_INSTANTIATED), 173 173 showflag(key, 'R', KEY_FLAG_REVOKED),
+101 -63
security/keys/process_keys.c
··· 39 39 .type = &key_type_keyring, 40 40 .user = &root_key_user, 41 41 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), 42 - .perm = KEY_USR_ALL, 42 + .perm = KEY_POS_ALL | KEY_USR_ALL, 43 43 .flags = 1 << KEY_FLAG_INSTANTIATED, 44 44 .description = "_uid.0", 45 45 #ifdef KEY_DEBUGGING ··· 54 54 .type = &key_type_keyring, 55 55 .user = &root_key_user, 56 56 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), 57 - .perm = KEY_USR_ALL, 57 + .perm = KEY_POS_ALL | KEY_USR_ALL, 58 58 .flags = 1 << KEY_FLAG_INSTANTIATED, 59 59 .description = "_uid_ses.0", 60 60 #ifdef KEY_DEBUGGING ··· 98 98 user->session_keyring = session_keyring; 99 99 ret = 0; 100 100 101 - error: 101 + error: 102 102 return ret; 103 103 104 104 } /* end alloc_uid_keyring() */ ··· 156 156 ret = 0; 157 157 158 158 key_put(old); 159 - error: 159 + error: 160 160 return ret; 161 161 162 162 } /* end install_thread_keyring() */ ··· 193 193 } 194 194 195 195 ret = 0; 196 - error: 196 + error: 197 197 return ret; 198 198 199 199 } /* end install_process_keyring() */ ··· 236 236 /* we're using RCU on the pointer */ 237 237 synchronize_rcu(); 238 238 key_put(old); 239 - error: 239 + error: 240 240 return ret; 241 241 242 242 } /* end install_session_keyring() */ ··· 376 376 * - we return -EAGAIN if we didn't find any matching key 377 377 * - we return -ENOKEY if we found only negative matching keys 378 378 */ 379 - struct key *search_process_keyrings(struct key_type *type, 380 - const void *description, 381 - key_match_func_t match, 382 - struct task_struct *context) 379 + key_ref_t search_process_keyrings(struct key_type *type, 380 + const void *description, 381 + key_match_func_t match, 382 + struct task_struct *context) 383 383 { 384 384 struct request_key_auth *rka; 385 - struct key *key, *ret, *err, *instkey; 385 + key_ref_t key_ref, ret, err, instkey_ref; 386 386 387 387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 388 388 * searchable, but we failed to find a key or we found a negative key; ··· 391 391 * 392 392 * in terms of priority: success > -ENOKEY > -EAGAIN > other error 393 393 */ 394 - key = NULL; 394 + key_ref = NULL; 395 395 ret = NULL; 396 396 err = ERR_PTR(-EAGAIN); 397 397 398 398 /* search the thread keyring first */ 399 399 if (context->thread_keyring) { 400 - key = keyring_search_aux(context->thread_keyring, 401 - context, type, description, match); 402 - if (!IS_ERR(key)) 400 + key_ref = keyring_search_aux( 401 + make_key_ref(context->thread_keyring, 1), 402 + context, type, description, match); 403 + if (!IS_ERR(key_ref)) 403 404 goto found; 404 405 405 - switch (PTR_ERR(key)) { 406 + switch (PTR_ERR(key_ref)) { 406 407 case -EAGAIN: /* no key */ 407 408 if (ret) 408 409 break; 409 410 case -ENOKEY: /* negative key */ 410 - ret = key; 411 + ret = key_ref; 411 412 break; 412 413 default: 413 - err = key; 414 + err = key_ref; 414 415 break; 415 416 } 416 417 } 417 418 418 419 /* search the process keyring second */ 419 420 if (context->signal->process_keyring) { 420 - key = keyring_search_aux(context->signal->process_keyring, 421 - context, type, description, match); 422 - if (!IS_ERR(key)) 421 + key_ref = keyring_search_aux( 422 + make_key_ref(context->signal->process_keyring, 1), 423 + context, type, description, match); 424 + if (!IS_ERR(key_ref)) 423 425 goto found; 424 426 425 - switch (PTR_ERR(key)) { 427 + switch (PTR_ERR(key_ref)) { 426 428 case -EAGAIN: /* no key */ 427 429 if (ret) 428 430 break; 429 431 case -ENOKEY: /* negative key */ 430 - ret = key; 432 + ret = key_ref; 431 433 break; 432 434 default: 433 - err = key; 435 + err = key_ref; 434 436 break; 435 437 } 436 438 } ··· 440 438 /* search the session keyring */ 441 439 if (context->signal->session_keyring) { 442 440 rcu_read_lock(); 443 - key = keyring_search_aux( 444 - rcu_dereference(context->signal->session_keyring), 441 + key_ref = keyring_search_aux( 442 + make_key_ref(rcu_dereference( 443 + context->signal->session_keyring), 444 + 1), 445 445 context, type, description, match); 446 446 rcu_read_unlock(); 447 447 448 - if (!IS_ERR(key)) 448 + if (!IS_ERR(key_ref)) 449 449 goto found; 450 450 451 - switch (PTR_ERR(key)) { 451 + switch (PTR_ERR(key_ref)) { 452 452 case -EAGAIN: /* no key */ 453 453 if (ret) 454 454 break; 455 455 case -ENOKEY: /* negative key */ 456 - ret = key; 456 + ret = key_ref; 457 457 break; 458 458 default: 459 - err = key; 459 + err = key_ref; 460 460 break; 461 461 } 462 462 ··· 469 465 goto no_key; 470 466 471 467 rcu_read_lock(); 472 - instkey = __keyring_search_one( 473 - rcu_dereference(context->signal->session_keyring), 468 + instkey_ref = __keyring_search_one( 469 + make_key_ref(rcu_dereference( 470 + context->signal->session_keyring), 471 + 1), 474 472 &key_type_request_key_auth, NULL, 0); 475 473 rcu_read_unlock(); 476 474 477 - if (IS_ERR(instkey)) 475 + if (IS_ERR(instkey_ref)) 478 476 goto no_key; 479 477 480 - rka = instkey->payload.data; 478 + rka = key_ref_to_ptr(instkey_ref)->payload.data; 481 479 482 - key = search_process_keyrings(type, description, match, 483 - rka->context); 484 - key_put(instkey); 480 + key_ref = search_process_keyrings(type, description, match, 481 + rka->context); 482 + key_ref_put(instkey_ref); 485 483 486 - if (!IS_ERR(key)) 484 + if (!IS_ERR(key_ref)) 487 485 goto found; 488 486 489 - switch (PTR_ERR(key)) { 487 + switch (PTR_ERR(key_ref)) { 490 488 case -EAGAIN: /* no key */ 491 489 if (ret) 492 490 break; 493 491 case -ENOKEY: /* negative key */ 494 - ret = key; 492 + ret = key_ref; 495 493 break; 496 494 default: 497 - err = key; 495 + err = key_ref; 498 496 break; 499 497 } 500 498 } 501 499 /* or search the user-session keyring */ 502 500 else { 503 - key = keyring_search_aux(context->user->session_keyring, 504 - context, type, description, match); 505 - if (!IS_ERR(key)) 501 + key_ref = keyring_search_aux( 502 + make_key_ref(context->user->session_keyring, 1), 503 + context, type, description, match); 504 + if (!IS_ERR(key_ref)) 506 505 goto found; 507 506 508 - switch (PTR_ERR(key)) { 507 + switch (PTR_ERR(key_ref)) { 509 508 case -EAGAIN: /* no key */ 510 509 if (ret) 511 510 break; 512 511 case -ENOKEY: /* negative key */ 513 - ret = key; 512 + ret = key_ref; 514 513 break; 515 514 default: 516 - err = key; 515 + err = key_ref; 517 516 break; 518 517 } 519 518 } ··· 524 517 525 518 no_key: 526 519 /* no key - decide on the error we're going to go for */ 527 - key = ret ? ret : err; 520 + key_ref = ret ? ret : err; 528 521 529 522 found: 530 - return key; 523 + return key_ref; 531 524 532 525 } /* end search_process_keyrings() */ 526 + 527 + /*****************************************************************************/ 528 + /* 529 + * see if the key we're looking at is the target key 530 + */ 531 + static int lookup_user_key_possessed(const struct key *key, const void *target) 532 + { 533 + return key == target; 534 + 535 + } /* end lookup_user_key_possessed() */ 533 536 534 537 /*****************************************************************************/ 535 538 /* ··· 547 530 * - don't create special keyrings unless so requested 548 531 * - partially constructed keys aren't found unless requested 549 532 */ 550 - struct key *lookup_user_key(struct task_struct *context, key_serial_t id, 551 - int create, int partial, key_perm_t perm) 533 + key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, 534 + int create, int partial, key_perm_t perm) 552 535 { 536 + key_ref_t key_ref, skey_ref; 553 537 struct key *key; 554 538 int ret; 555 539 556 540 if (!context) 557 541 context = current; 558 542 559 - key = ERR_PTR(-ENOKEY); 543 + key_ref = ERR_PTR(-ENOKEY); 560 544 561 545 switch (id) { 562 546 case KEY_SPEC_THREAD_KEYRING: ··· 574 556 575 557 key = context->thread_keyring; 576 558 atomic_inc(&key->usage); 559 + key_ref = make_key_ref(key, 1); 577 560 break; 578 561 579 562 case KEY_SPEC_PROCESS_KEYRING: ··· 591 572 592 573 key = context->signal->process_keyring; 593 574 atomic_inc(&key->usage); 575 + key_ref = make_key_ref(key, 1); 594 576 break; 595 577 596 578 case KEY_SPEC_SESSION_KEYRING: ··· 599 579 /* always install a session keyring upon access if one 600 580 * doesn't exist yet */ 601 581 ret = install_session_keyring( 602 - context, context->user->session_keyring); 582 + context, context->user->session_keyring); 603 583 if (ret < 0) 604 584 goto error; 605 585 } ··· 608 588 key = rcu_dereference(context->signal->session_keyring); 609 589 atomic_inc(&key->usage); 610 590 rcu_read_unlock(); 591 + key_ref = make_key_ref(key, 1); 611 592 break; 612 593 613 594 case KEY_SPEC_USER_KEYRING: 614 595 key = context->user->uid_keyring; 615 596 atomic_inc(&key->usage); 597 + key_ref = make_key_ref(key, 1); 616 598 break; 617 599 618 600 case KEY_SPEC_USER_SESSION_KEYRING: 619 601 key = context->user->session_keyring; 620 602 atomic_inc(&key->usage); 603 + key_ref = make_key_ref(key, 1); 621 604 break; 622 605 623 606 case KEY_SPEC_GROUP_KEYRING: ··· 629 606 goto error; 630 607 631 608 default: 632 - key = ERR_PTR(-EINVAL); 609 + key_ref = ERR_PTR(-EINVAL); 633 610 if (id < 1) 634 611 goto error; 635 612 636 613 key = key_lookup(id); 637 - if (IS_ERR(key)) 614 + if (IS_ERR(key)) { 615 + key_ref = ERR_PTR(PTR_ERR(key)); 638 616 goto error; 617 + } 618 + 619 + key_ref = make_key_ref(key, 0); 620 + 621 + /* check to see if we possess the key */ 622 + skey_ref = search_process_keyrings(key->type, key, 623 + lookup_user_key_possessed, 624 + current); 625 + 626 + if (!IS_ERR(skey_ref)) { 627 + key_put(key); 628 + key_ref = skey_ref; 629 + } 630 + 639 631 break; 640 632 } 641 633 ··· 668 630 /* check the permissions */ 669 631 ret = -EACCES; 670 632 671 - if (!key_task_permission(key, context, perm)) 633 + if (!key_task_permission(key_ref, context, perm)) 672 634 goto invalid_key; 673 635 674 - error: 675 - return key; 636 + error: 637 + return key_ref; 676 638 677 - invalid_key: 678 - key_put(key); 679 - key = ERR_PTR(ret); 639 + invalid_key: 640 + key_ref_put(key_ref); 641 + key_ref = ERR_PTR(ret); 680 642 goto error; 681 643 682 644 } /* end lookup_user_key() */ ··· 732 694 ret = keyring->serial; 733 695 key_put(keyring); 734 696 735 - error2: 697 + error2: 736 698 up(&key_session_sem); 737 - error: 699 + error: 738 700 return ret; 739 701 740 702 } /* end join_session_keyring() */
+29 -7
security/keys/request_key.c
··· 129 129 130 130 /* create a key and add it to the queue */ 131 131 key = key_alloc(type, description, 132 - current->fsuid, current->fsgid, KEY_USR_ALL, 0); 132 + current->fsuid, current->fsgid, KEY_POS_ALL, 0); 133 133 if (IS_ERR(key)) 134 134 goto alloc_failed; 135 135 ··· 365 365 { 366 366 struct key_user *user; 367 367 struct key *key; 368 + key_ref_t key_ref; 368 369 369 370 kenter("%s,%s,%s,%p", 370 371 type->name, description, callout_info, dest_keyring); 371 372 372 373 /* search all the process keyrings for a key */ 373 - key = search_process_keyrings(type, description, type->match, current); 374 + key_ref = search_process_keyrings(type, description, type->match, 375 + current); 374 376 375 - if (PTR_ERR(key) == -EAGAIN) { 377 + kdebug("search 1: %p", key_ref); 378 + 379 + if (!IS_ERR(key_ref)) { 380 + key = key_ref_to_ptr(key_ref); 381 + } 382 + else if (PTR_ERR(key_ref) != -EAGAIN) { 383 + key = ERR_PTR(PTR_ERR(key_ref)); 384 + } 385 + else { 376 386 /* the search failed, but the keyrings were searchable, so we 377 387 * should consult userspace if we can */ 378 388 key = ERR_PTR(-ENOKEY); ··· 394 384 if (!user) 395 385 goto nomem; 396 386 397 - do { 387 + for (;;) { 398 388 if (signal_pending(current)) 399 389 goto interrupted; 400 390 ··· 407 397 408 398 /* someone else made the key we want, so we need to 409 399 * search again as it might now be available to us */ 410 - key = search_process_keyrings(type, description, 411 - type->match, current); 400 + key_ref = search_process_keyrings(type, description, 401 + type->match, 402 + current); 412 403 413 - } while (PTR_ERR(key) == -EAGAIN); 404 + kdebug("search 2: %p", key_ref); 405 + 406 + if (!IS_ERR(key_ref)) { 407 + key = key_ref_to_ptr(key_ref); 408 + break; 409 + } 410 + 411 + if (PTR_ERR(key_ref) != -EAGAIN) { 412 + key = ERR_PTR(PTR_ERR(key_ref)); 413 + break; 414 + } 415 + } 414 416 415 417 key_user_put(user); 416 418
+1 -1
security/keys/request_key_auth.c
··· 126 126 127 127 rkakey = key_alloc(&key_type_request_key_auth, desc, 128 128 current->fsuid, current->fsgid, 129 - KEY_USR_VIEW, 1); 129 + KEY_POS_VIEW | KEY_USR_VIEW, 1); 130 130 if (IS_ERR(rkakey)) { 131 131 key_put(keyring); 132 132 kleave("= %ld", PTR_ERR(rkakey));