diff options
| author | David Howells <dhowells@redhat.com> | 2006-01-06 03:11:24 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:29 -0500 |
| commit | 8d9067bda99c68e1a17d93e78cf3a5a3f67e0c35 (patch) | |
| tree | 6f3c7fe665012c456b57840c290eafd4deabbeb2 | |
| parent | 32725ad8430b58e42c5d54757ce7871e680d05cb (diff) | |
[PATCH] Keys: Remove key duplication
Remove the key duplication stuff since there's nothing that uses it, no way
to get at it and it's awkward to deal with for LSM purposes.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | Documentation/keys.txt | 18 | ||||
| -rw-r--r-- | include/keys/user-type.h | 1 | ||||
| -rw-r--r-- | include/linux/key.h | 8 | ||||
| -rw-r--r-- | security/keys/key.c | 56 | ||||
| -rw-r--r-- | security/keys/keyring.c | 64 | ||||
| -rw-r--r-- | security/keys/user_defined.c | 33 |
6 files changed, 3 insertions, 177 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 31154882000a..6304db59bfe4 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
| @@ -860,24 +860,6 @@ The structure has a number of fields, some of which are mandatory: | |||
| 860 | It is safe to sleep in this method. | 860 | It is safe to sleep in this method. |
| 861 | 861 | ||
| 862 | 862 | ||
| 863 | (*) int (*duplicate)(struct key *key, const struct key *source); | ||
| 864 | |||
| 865 | If this type of key can be duplicated, then this method should be | ||
| 866 | provided. It is called to copy the payload attached to the source into the | ||
| 867 | new key. The data length on the new key will have been updated and the | ||
| 868 | quota adjusted already. | ||
| 869 | |||
| 870 | This method will be called with the source key's semaphore read-locked to | ||
| 871 | prevent its payload from being changed, thus RCU constraints need not be | ||
| 872 | applied to the source key. | ||
| 873 | |||
| 874 | This method does not have to lock the destination key in order to attach a | ||
| 875 | payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags | ||
| 876 | prevents anything else from gaining access to the key. | ||
| 877 | |||
| 878 | It is safe to sleep in this method. | ||
| 879 | |||
| 880 | |||
| 881 | (*) int (*update)(struct key *key, const void *data, size_t datalen); | 863 | (*) int (*update)(struct key *key, const void *data, size_t datalen); |
| 882 | 864 | ||
| 883 | If this type of key can be updated, then this method should be provided. | 865 | If this type of key can be updated, then this method should be provided. |
diff --git a/include/keys/user-type.h b/include/keys/user-type.h index 26f6ec38577a..a3dae1803f45 100644 --- a/include/keys/user-type.h +++ b/include/keys/user-type.h | |||
| @@ -35,7 +35,6 @@ struct user_key_payload { | |||
| 35 | extern struct key_type key_type_user; | 35 | extern struct key_type key_type_user; |
| 36 | 36 | ||
| 37 | extern int user_instantiate(struct key *key, const void *data, size_t datalen); | 37 | extern int user_instantiate(struct key *key, const void *data, size_t datalen); |
| 38 | extern int user_duplicate(struct key *key, const struct key *source); | ||
| 39 | extern int user_update(struct key *key, const void *data, size_t datalen); | 38 | extern int user_update(struct key *key, const void *data, size_t datalen); |
| 40 | extern int user_match(const struct key *key, const void *criterion); | 39 | extern int user_match(const struct key *key, const void *criterion); |
| 41 | extern void user_destroy(struct key *key); | 40 | extern void user_destroy(struct key *key); |
diff --git a/include/linux/key.h b/include/linux/key.h index 53513a3be53b..4d189e51bc6c 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
| @@ -193,14 +193,6 @@ struct key_type { | |||
| 193 | */ | 193 | */ |
| 194 | int (*instantiate)(struct key *key, const void *data, size_t datalen); | 194 | int (*instantiate)(struct key *key, const void *data, size_t datalen); |
| 195 | 195 | ||
| 196 | /* duplicate a key of this type (optional) | ||
| 197 | * - the source key will be locked against change | ||
| 198 | * - the new description will be attached | ||
| 199 | * - the quota will have been adjusted automatically from | ||
| 200 | * source->quotalen | ||
| 201 | */ | ||
| 202 | int (*duplicate)(struct key *key, const struct key *source); | ||
| 203 | |||
| 204 | /* update a key of this type (optional) | 196 | /* update a key of this type (optional) |
| 205 | * - this method should call key_payload_reserve() to recalculate the | 197 | * - this method should call key_payload_reserve() to recalculate the |
| 206 | * quota consumption | 198 | * quota consumption |
diff --git a/security/keys/key.c b/security/keys/key.c index 01bcfecb7eae..bb036623d0a8 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
| @@ -240,9 +240,9 @@ static inline void key_alloc_serial(struct key *key) | |||
| 240 | /* | 240 | /* |
| 241 | * allocate a key of the specified type | 241 | * allocate a key of the specified type |
| 242 | * - update the user's quota to reflect the existence of the key | 242 | * - update the user's quota to reflect the existence of the key |
| 243 | * - called from a key-type operation with key_types_sem read-locked by either | 243 | * - called from a key-type operation with key_types_sem read-locked by |
| 244 | * key_create_or_update() or by key_duplicate(); this prevents unregistration | 244 | * key_create_or_update() |
| 245 | * of the key type | 245 | * - this prevents unregistration of the key type |
| 246 | * - upon return the key is as yet uninstantiated; the caller needs to either | 246 | * - upon return the key is as yet uninstantiated; the caller needs to either |
| 247 | * instantiate the key or discard it before returning | 247 | * instantiate the key or discard it before returning |
| 248 | */ | 248 | */ |
| @@ -889,56 +889,6 @@ EXPORT_SYMBOL(key_update); | |||
| 889 | 889 | ||
| 890 | /*****************************************************************************/ | 890 | /*****************************************************************************/ |
| 891 | /* | 891 | /* |
| 892 | * duplicate a key, potentially with a revised description | ||
| 893 | * - must be supported by the keytype (keyrings for instance can be duplicated) | ||
| 894 | */ | ||
| 895 | struct key *key_duplicate(struct key *source, const char *desc) | ||
| 896 | { | ||
| 897 | struct key *key; | ||
| 898 | int ret; | ||
| 899 | |||
| 900 | key_check(source); | ||
| 901 | |||
| 902 | if (!desc) | ||
| 903 | desc = source->description; | ||
| 904 | |||
| 905 | down_read(&key_types_sem); | ||
| 906 | |||
| 907 | ret = -EINVAL; | ||
| 908 | if (!source->type->duplicate) | ||
| 909 | goto error; | ||
| 910 | |||
| 911 | /* allocate and instantiate a key */ | ||
| 912 | key = key_alloc(source->type, desc, current->fsuid, current->fsgid, | ||
| 913 | source->perm, 0); | ||
| 914 | if (IS_ERR(key)) | ||
| 915 | goto error_k; | ||
| 916 | |||
| 917 | down_read(&source->sem); | ||
| 918 | ret = key->type->duplicate(key, source); | ||
| 919 | up_read(&source->sem); | ||
| 920 | if (ret < 0) | ||
| 921 | goto error2; | ||
| 922 | |||
| 923 | atomic_inc(&key->user->nikeys); | ||
| 924 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); | ||
| 925 | |||
| 926 | error_k: | ||
| 927 | up_read(&key_types_sem); | ||
| 928 | out: | ||
| 929 | return key; | ||
| 930 | |||
| 931 | error2: | ||
| 932 | key_put(key); | ||
| 933 | error: | ||
| 934 | up_read(&key_types_sem); | ||
| 935 | key = ERR_PTR(ret); | ||
| 936 | goto out; | ||
| 937 | |||
| 938 | } /* end key_duplicate() */ | ||
| 939 | |||
| 940 | /*****************************************************************************/ | ||
| 941 | /* | ||
| 942 | * revoke a key | 892 | * revoke a key |
| 943 | */ | 893 | */ |
| 944 | void key_revoke(struct key *key) | 894 | void key_revoke(struct key *key) |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 4e9fa8be44b8..0acecbd4fa37 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
| @@ -48,7 +48,6 @@ static inline unsigned keyring_hash(const char *desc) | |||
| 48 | */ | 48 | */ |
| 49 | static int keyring_instantiate(struct key *keyring, | 49 | static int keyring_instantiate(struct key *keyring, |
| 50 | const void *data, size_t datalen); | 50 | const void *data, size_t datalen); |
| 51 | static int keyring_duplicate(struct key *keyring, const struct key *source); | ||
| 52 | static int keyring_match(const struct key *keyring, const void *criterion); | 51 | static int keyring_match(const struct key *keyring, const void *criterion); |
| 53 | static void keyring_destroy(struct key *keyring); | 52 | static void keyring_destroy(struct key *keyring); |
| 54 | static void keyring_describe(const struct key *keyring, struct seq_file *m); | 53 | static void keyring_describe(const struct key *keyring, struct seq_file *m); |
| @@ -59,7 +58,6 @@ struct key_type key_type_keyring = { | |||
| 59 | .name = "keyring", | 58 | .name = "keyring", |
| 60 | .def_datalen = sizeof(struct keyring_list), | 59 | .def_datalen = sizeof(struct keyring_list), |
| 61 | .instantiate = keyring_instantiate, | 60 | .instantiate = keyring_instantiate, |
| 62 | .duplicate = keyring_duplicate, | ||
| 63 | .match = keyring_match, | 61 | .match = keyring_match, |
| 64 | .destroy = keyring_destroy, | 62 | .destroy = keyring_destroy, |
| 65 | .describe = keyring_describe, | 63 | .describe = keyring_describe, |
| @@ -120,68 +118,6 @@ static int keyring_instantiate(struct key *keyring, | |||
| 120 | 118 | ||
| 121 | /*****************************************************************************/ | 119 | /*****************************************************************************/ |
| 122 | /* | 120 | /* |
| 123 | * duplicate the list of subscribed keys from a source keyring into this one | ||
| 124 | */ | ||
| 125 | static int keyring_duplicate(struct key *keyring, const struct key *source) | ||
| 126 | { | ||
| 127 | struct keyring_list *sklist, *klist; | ||
| 128 | unsigned max; | ||
| 129 | size_t size; | ||
| 130 | int loop, ret; | ||
| 131 | |||
| 132 | const unsigned limit = | ||
| 133 | (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *); | ||
| 134 | |||
| 135 | ret = 0; | ||
| 136 | |||
| 137 | /* find out how many keys are currently linked */ | ||
| 138 | rcu_read_lock(); | ||
| 139 | sklist = rcu_dereference(source->payload.subscriptions); | ||
| 140 | max = 0; | ||
| 141 | if (sklist) | ||
| 142 | max = sklist->nkeys; | ||
| 143 | rcu_read_unlock(); | ||
| 144 | |||
| 145 | /* allocate a new payload and stuff load with key links */ | ||
| 146 | if (max > 0) { | ||
| 147 | BUG_ON(max > limit); | ||
| 148 | |||
| 149 | max = (max + 3) & ~3; | ||
| 150 | if (max > limit) | ||
| 151 | max = limit; | ||
| 152 | |||
| 153 | ret = -ENOMEM; | ||
| 154 | size = sizeof(*klist) + sizeof(struct key *) * max; | ||
| 155 | klist = kmalloc(size, GFP_KERNEL); | ||
| 156 | if (!klist) | ||
| 157 | goto error; | ||
| 158 | |||
| 159 | /* set links */ | ||
| 160 | rcu_read_lock(); | ||
| 161 | sklist = rcu_dereference(source->payload.subscriptions); | ||
| 162 | |||
| 163 | klist->maxkeys = max; | ||
| 164 | klist->nkeys = sklist->nkeys; | ||
| 165 | memcpy(klist->keys, | ||
| 166 | sklist->keys, | ||
| 167 | sklist->nkeys * sizeof(struct key *)); | ||
| 168 | |||
| 169 | for (loop = klist->nkeys - 1; loop >= 0; loop--) | ||
| 170 | atomic_inc(&klist->keys[loop]->usage); | ||
| 171 | |||
| 172 | rcu_read_unlock(); | ||
| 173 | |||
| 174 | rcu_assign_pointer(keyring->payload.subscriptions, klist); | ||
| 175 | ret = 0; | ||
| 176 | } | ||
| 177 | |||
| 178 | error: | ||
| 179 | return ret; | ||
| 180 | |||
| 181 | } /* end keyring_duplicate() */ | ||
| 182 | |||
| 183 | /*****************************************************************************/ | ||
| 184 | /* | ||
| 185 | * match keyrings on their name | 121 | * match keyrings on their name |
| 186 | */ | 122 | */ |
| 187 | static int keyring_match(const struct key *keyring, const void *description) | 123 | static int keyring_match(const struct key *keyring, const void *description) |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index cbda3b2780a1..8e71895b97a7 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | struct key_type key_type_user = { | 26 | struct key_type key_type_user = { |
| 27 | .name = "user", | 27 | .name = "user", |
| 28 | .instantiate = user_instantiate, | 28 | .instantiate = user_instantiate, |
| 29 | .duplicate = user_duplicate, | ||
| 30 | .update = user_update, | 29 | .update = user_update, |
| 31 | .match = user_match, | 30 | .match = user_match, |
| 32 | .destroy = user_destroy, | 31 | .destroy = user_destroy, |
| @@ -68,42 +67,10 @@ error: | |||
| 68 | return ret; | 67 | return ret; |
| 69 | 68 | ||
| 70 | } /* end user_instantiate() */ | 69 | } /* end user_instantiate() */ |
| 71 | |||
| 72 | EXPORT_SYMBOL_GPL(user_instantiate); | 70 | EXPORT_SYMBOL_GPL(user_instantiate); |
| 73 | 71 | ||
| 74 | /*****************************************************************************/ | 72 | /*****************************************************************************/ |
| 75 | /* | 73 | /* |
| 76 | * duplicate a user defined key | ||
| 77 | * - both keys' semaphores are locked against further modification | ||
| 78 | * - the new key cannot yet be accessed | ||
| 79 | */ | ||
| 80 | int user_duplicate(struct key *key, const struct key *source) | ||
| 81 | { | ||
| 82 | struct user_key_payload *upayload, *spayload; | ||
| 83 | int ret; | ||
| 84 | |||
| 85 | /* just copy the payload */ | ||
| 86 | ret = -ENOMEM; | ||
| 87 | upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL); | ||
| 88 | if (upayload) { | ||
| 89 | spayload = rcu_dereference(source->payload.data); | ||
| 90 | BUG_ON(source->datalen != spayload->datalen); | ||
| 91 | |||
| 92 | upayload->datalen = key->datalen = spayload->datalen; | ||
| 93 | memcpy(upayload->data, spayload->data, key->datalen); | ||
| 94 | |||
| 95 | key->payload.data = upayload; | ||
| 96 | ret = 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | return ret; | ||
| 100 | |||
| 101 | } /* end user_duplicate() */ | ||
| 102 | |||
| 103 | EXPORT_SYMBOL_GPL(user_duplicate); | ||
| 104 | |||
| 105 | /*****************************************************************************/ | ||
| 106 | /* | ||
| 107 | * dispose of the old data from an updated user defined key | 74 | * dispose of the old data from an updated user defined key |
| 108 | */ | 75 | */ |
| 109 | static void user_update_rcu_disposal(struct rcu_head *rcu) | 76 | static void user_update_rcu_disposal(struct rcu_head *rcu) |
