diff options
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r-- | security/keys/request_key.c | 72 |
1 files changed, 29 insertions, 43 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 301f0e300dbd..3f56a312dd35 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -18,31 +18,30 @@ | |||
18 | #include <linux/keyctl.h> | 18 | #include <linux/keyctl.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include "internal.h" | 20 | #include "internal.h" |
21 | #include <keys/request_key_auth-type.h> | ||
21 | 22 | ||
22 | #define key_negative_timeout 60 /* default timeout on a negative key's existence */ | 23 | #define key_negative_timeout 60 /* default timeout on a negative key's existence */ |
23 | 24 | ||
24 | /** | 25 | /** |
25 | * complete_request_key - Complete the construction of a key. | 26 | * complete_request_key - Complete the construction of a key. |
26 | * @cons: The key construction record. | 27 | * @auth_key: The authorisation key. |
27 | * @error: The success or failute of the construction. | 28 | * @error: The success or failute of the construction. |
28 | * | 29 | * |
29 | * Complete the attempt to construct a key. The key will be negated | 30 | * Complete the attempt to construct a key. The key will be negated |
30 | * if an error is indicated. The authorisation key will be revoked | 31 | * if an error is indicated. The authorisation key will be revoked |
31 | * unconditionally. | 32 | * unconditionally. |
32 | */ | 33 | */ |
33 | void complete_request_key(struct key_construction *cons, int error) | 34 | void complete_request_key(struct key *authkey, int error) |
34 | { | 35 | { |
35 | kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error); | 36 | struct request_key_auth *rka = get_request_key_auth(authkey); |
37 | struct key *key = rka->target_key; | ||
38 | |||
39 | kenter("%d{%d},%d", authkey->serial, key->serial, error); | ||
36 | 40 | ||
37 | if (error < 0) | 41 | if (error < 0) |
38 | key_negate_and_link(cons->key, key_negative_timeout, NULL, | 42 | key_negate_and_link(key, key_negative_timeout, NULL, authkey); |
39 | cons->authkey); | ||
40 | else | 43 | else |
41 | key_revoke(cons->authkey); | 44 | key_revoke(authkey); |
42 | |||
43 | key_put(cons->key); | ||
44 | key_put(cons->authkey); | ||
45 | kfree(cons); | ||
46 | } | 45 | } |
47 | EXPORT_SYMBOL(complete_request_key); | 46 | EXPORT_SYMBOL(complete_request_key); |
48 | 47 | ||
@@ -91,21 +90,19 @@ static int call_usermodehelper_keys(const char *path, char **argv, char **envp, | |||
91 | * Request userspace finish the construction of a key | 90 | * Request userspace finish the construction of a key |
92 | * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" | 91 | * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" |
93 | */ | 92 | */ |
94 | static int call_sbin_request_key(struct key_construction *cons, | 93 | static int call_sbin_request_key(struct key *authkey, void *aux) |
95 | const char *op, | ||
96 | void *aux) | ||
97 | { | 94 | { |
98 | static char const request_key[] = "/sbin/request-key"; | 95 | static char const request_key[] = "/sbin/request-key"; |
96 | struct request_key_auth *rka = get_request_key_auth(authkey); | ||
99 | const struct cred *cred = current_cred(); | 97 | const struct cred *cred = current_cred(); |
100 | key_serial_t prkey, sskey; | 98 | key_serial_t prkey, sskey; |
101 | struct key *key = cons->key, *authkey = cons->authkey, *keyring, | 99 | struct key *key = rka->target_key, *keyring, *session; |
102 | *session; | ||
103 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; | 100 | char *argv[9], *envp[3], uid_str[12], gid_str[12]; |
104 | char key_str[12], keyring_str[3][12]; | 101 | char key_str[12], keyring_str[3][12]; |
105 | char desc[20]; | 102 | char desc[20]; |
106 | int ret, i; | 103 | int ret, i; |
107 | 104 | ||
108 | kenter("{%d},{%d},%s", key->serial, authkey->serial, op); | 105 | kenter("{%d},{%d},%s", key->serial, authkey->serial, rka->op); |
109 | 106 | ||
110 | ret = install_user_keyrings(); | 107 | ret = install_user_keyrings(); |
111 | if (ret < 0) | 108 | if (ret < 0) |
@@ -163,7 +160,7 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
163 | /* set up the argument list */ | 160 | /* set up the argument list */ |
164 | i = 0; | 161 | i = 0; |
165 | argv[i++] = (char *)request_key; | 162 | argv[i++] = (char *)request_key; |
166 | argv[i++] = (char *) op; | 163 | argv[i++] = (char *)rka->op; |
167 | argv[i++] = key_str; | 164 | argv[i++] = key_str; |
168 | argv[i++] = uid_str; | 165 | argv[i++] = uid_str; |
169 | argv[i++] = gid_str; | 166 | argv[i++] = gid_str; |
@@ -191,7 +188,7 @@ error_link: | |||
191 | key_put(keyring); | 188 | key_put(keyring); |
192 | 189 | ||
193 | error_alloc: | 190 | error_alloc: |
194 | complete_request_key(cons, ret); | 191 | complete_request_key(authkey, ret); |
195 | kleave(" = %d", ret); | 192 | kleave(" = %d", ret); |
196 | return ret; | 193 | return ret; |
197 | } | 194 | } |
@@ -205,42 +202,31 @@ static int construct_key(struct key *key, const void *callout_info, | |||
205 | size_t callout_len, void *aux, | 202 | size_t callout_len, void *aux, |
206 | struct key *dest_keyring) | 203 | struct key *dest_keyring) |
207 | { | 204 | { |
208 | struct key_construction *cons; | ||
209 | request_key_actor_t actor; | 205 | request_key_actor_t actor; |
210 | struct key *authkey; | 206 | struct key *authkey; |
211 | int ret; | 207 | int ret; |
212 | 208 | ||
213 | kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); | 209 | kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); |
214 | 210 | ||
215 | cons = kmalloc(sizeof(*cons), GFP_KERNEL); | ||
216 | if (!cons) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | /* allocate an authorisation key */ | 211 | /* allocate an authorisation key */ |
220 | authkey = request_key_auth_new(key, callout_info, callout_len, | 212 | authkey = request_key_auth_new(key, "create", callout_info, callout_len, |
221 | dest_keyring); | 213 | dest_keyring); |
222 | if (IS_ERR(authkey)) { | 214 | if (IS_ERR(authkey)) |
223 | kfree(cons); | 215 | return PTR_ERR(authkey); |
224 | ret = PTR_ERR(authkey); | ||
225 | authkey = NULL; | ||
226 | } else { | ||
227 | cons->authkey = key_get(authkey); | ||
228 | cons->key = key_get(key); | ||
229 | 216 | ||
230 | /* make the call */ | 217 | /* Make the call */ |
231 | actor = call_sbin_request_key; | 218 | actor = call_sbin_request_key; |
232 | if (key->type->request_key) | 219 | if (key->type->request_key) |
233 | actor = key->type->request_key; | 220 | actor = key->type->request_key; |
234 | 221 | ||
235 | ret = actor(cons, "create", aux); | 222 | ret = actor(authkey, aux); |
236 | 223 | ||
237 | /* check that the actor called complete_request_key() prior to | 224 | /* check that the actor called complete_request_key() prior to |
238 | * returning an error */ | 225 | * returning an error */ |
239 | WARN_ON(ret < 0 && | 226 | WARN_ON(ret < 0 && |
240 | !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); | 227 | !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); |
241 | key_put(authkey); | ||
242 | } | ||
243 | 228 | ||
229 | key_put(authkey); | ||
244 | kleave(" = %d", ret); | 230 | kleave(" = %d", ret); |
245 | return ret; | 231 | return ret; |
246 | } | 232 | } |
@@ -275,7 +261,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring) | |||
275 | if (cred->request_key_auth) { | 261 | if (cred->request_key_auth) { |
276 | authkey = cred->request_key_auth; | 262 | authkey = cred->request_key_auth; |
277 | down_read(&authkey->sem); | 263 | down_read(&authkey->sem); |
278 | rka = authkey->payload.data[0]; | 264 | rka = get_request_key_auth(authkey); |
279 | if (!test_bit(KEY_FLAG_REVOKED, | 265 | if (!test_bit(KEY_FLAG_REVOKED, |
280 | &authkey->flags)) | 266 | &authkey->flags)) |
281 | dest_keyring = | 267 | dest_keyring = |