aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c221
1 files changed, 168 insertions, 53 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 9705b1aeba5d..dfcd983af1fd 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,6 +1,6 @@
1/* request_key.c: request a key from userspace 1/* request_key.c: request a key from userspace
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/kmod.h> 14#include <linux/kmod.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/keyctl.h>
16#include "internal.h" 17#include "internal.h"
17 18
18struct key_construction { 19struct key_construction {
@@ -27,18 +28,26 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
27/* 28/*
28 * request userspace finish the construction of a key 29 * request userspace finish the construction of a key
29 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 30 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
30 * - if callout_info is an empty string, it'll be rendered as a "-" instead
31 */ 31 */
32static int call_request_key(struct key *key, 32static int call_request_key(struct key *key,
33 const char *op, 33 const char *op,
34 const char *callout_info) 34 const char *callout_info)
35{ 35{
36 struct task_struct *tsk = current; 36 struct task_struct *tsk = current;
37 unsigned long flags;
38 key_serial_t prkey, sskey; 37 key_serial_t prkey, sskey;
38 struct key *session_keyring, *rkakey;
39 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 39 char *argv[10], *envp[3], uid_str[12], gid_str[12];
40 char key_str[12], keyring_str[3][12]; 40 char key_str[12], keyring_str[3][12];
41 int i; 41 int ret, i;
42
43 kenter("{%d},%s,%s", key->serial, op, callout_info);
44
45 /* generate a new session keyring with an auth key in it */
46 session_keyring = request_key_auth_new(key, &rkakey);
47 if (IS_ERR(session_keyring)) {
48 ret = PTR_ERR(session_keyring);
49 goto error;
50 }
42 51
43 /* record the UID and GID */ 52 /* record the UID and GID */
44 sprintf(uid_str, "%d", current->fsuid); 53 sprintf(uid_str, "%d", current->fsuid);
@@ -55,17 +64,17 @@ static int call_request_key(struct key *key,
55 if (tsk->signal->process_keyring) 64 if (tsk->signal->process_keyring)
56 prkey = tsk->signal->process_keyring->serial; 65 prkey = tsk->signal->process_keyring->serial;
57 66
58 sskey = 0; 67 sprintf(keyring_str[1], "%d", prkey);
59 spin_lock_irqsave(&tsk->sighand->siglock, flags);
60 if (tsk->signal->session_keyring)
61 sskey = tsk->signal->session_keyring->serial;
62 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
63
64 68
65 if (!sskey) 69 if (tsk->signal->session_keyring) {
70 rcu_read_lock();
71 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
72 rcu_read_unlock();
73 }
74 else {
66 sskey = tsk->user->session_keyring->serial; 75 sskey = tsk->user->session_keyring->serial;
76 }
67 77
68 sprintf(keyring_str[1], "%d", prkey);
69 sprintf(keyring_str[2], "%d", sskey); 78 sprintf(keyring_str[2], "%d", sskey);
70 79
71 /* set up a minimal environment */ 80 /* set up a minimal environment */
@@ -84,11 +93,20 @@ static int call_request_key(struct key *key,
84 argv[i++] = keyring_str[0]; 93 argv[i++] = keyring_str[0];
85 argv[i++] = keyring_str[1]; 94 argv[i++] = keyring_str[1];
86 argv[i++] = keyring_str[2]; 95 argv[i++] = keyring_str[2];
87 argv[i++] = callout_info[0] ? (char *) callout_info : "-"; 96 argv[i++] = (char *) callout_info;
88 argv[i] = NULL; 97 argv[i] = NULL;
89 98
90 /* do it */ 99 /* do it */
91 return call_usermodehelper(argv[0], argv, envp, 1); 100 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
101
102 /* dispose of the special keys */
103 key_revoke(rkakey);
104 key_put(rkakey);
105 key_put(session_keyring);
106
107 error:
108 kleave(" = %d", ret);
109 return ret;
92 110
93} /* end call_request_key() */ 111} /* end call_request_key() */
94 112
@@ -105,7 +123,9 @@ static struct key *__request_key_construction(struct key_type *type,
105 struct key_construction cons; 123 struct key_construction cons;
106 struct timespec now; 124 struct timespec now;
107 struct key *key; 125 struct key *key;
108 int ret, negative; 126 int ret, negated;
127
128 kenter("%s,%s,%s", type->name, description, callout_info);
109 129
110 /* create a key and add it to the queue */ 130 /* create a key and add it to the queue */
111 key = key_alloc(type, description, 131 key = key_alloc(type, description,
@@ -113,9 +133,7 @@ static struct key *__request_key_construction(struct key_type *type,
113 if (IS_ERR(key)) 133 if (IS_ERR(key))
114 goto alloc_failed; 134 goto alloc_failed;
115 135
116 write_lock(&key->lock); 136 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
117 key->flags |= KEY_FLAG_USER_CONSTRUCT;
118 write_unlock(&key->lock);
119 137
120 cons.key = key; 138 cons.key = key;
121 list_add_tail(&cons.link, &key->user->consq); 139 list_add_tail(&cons.link, &key->user->consq);
@@ -130,7 +148,7 @@ static struct key *__request_key_construction(struct key_type *type,
130 148
131 /* if the key wasn't instantiated, then we want to give an error */ 149 /* if the key wasn't instantiated, then we want to give an error */
132 ret = -ENOKEY; 150 ret = -ENOKEY;
133 if (!(key->flags & KEY_FLAG_INSTANTIATED)) 151 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
134 goto request_failed; 152 goto request_failed;
135 153
136 down_write(&key_construction_sem); 154 down_write(&key_construction_sem);
@@ -139,12 +157,13 @@ static struct key *__request_key_construction(struct key_type *type,
139 157
140 /* also give an error if the key was negatively instantiated */ 158 /* also give an error if the key was negatively instantiated */
141 check_not_negative: 159 check_not_negative:
142 if (key->flags & KEY_FLAG_NEGATIVE) { 160 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
143 key_put(key); 161 key_put(key);
144 key = ERR_PTR(-ENOKEY); 162 key = ERR_PTR(-ENOKEY);
145 } 163 }
146 164
147 out: 165 out:
166 kleave(" = %p", key);
148 return key; 167 return key;
149 168
150 request_failed: 169 request_failed:
@@ -152,24 +171,23 @@ static struct key *__request_key_construction(struct key_type *type,
152 * - remove from construction queue 171 * - remove from construction queue
153 * - mark the key as dead 172 * - mark the key as dead
154 */ 173 */
155 negative = 0; 174 negated = 0;
156 down_write(&key_construction_sem); 175 down_write(&key_construction_sem);
157 176
158 list_del(&cons.link); 177 list_del(&cons.link);
159 178
160 write_lock(&key->lock);
161 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
162
163 /* check it didn't get instantiated between the check and the down */ 179 /* check it didn't get instantiated between the check and the down */
164 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 180 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
165 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; 181 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
166 negative = 1; 182 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
183 negated = 1;
167 } 184 }
168 185
169 write_unlock(&key->lock); 186 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
187
170 up_write(&key_construction_sem); 188 up_write(&key_construction_sem);
171 189
172 if (!negative) 190 if (!negated)
173 goto check_not_negative; /* surprisingly, the key got 191 goto check_not_negative; /* surprisingly, the key got
174 * instantiated */ 192 * instantiated */
175 193
@@ -178,13 +196,12 @@ static struct key *__request_key_construction(struct key_type *type,
178 key->expiry = now.tv_sec + key_negative_timeout; 196 key->expiry = now.tv_sec + key_negative_timeout;
179 197
180 if (current->signal->session_keyring) { 198 if (current->signal->session_keyring) {
181 unsigned long flags;
182 struct key *keyring; 199 struct key *keyring;
183 200
184 spin_lock_irqsave(&current->sighand->siglock, flags); 201 rcu_read_lock();
185 keyring = current->signal->session_keyring; 202 keyring = rcu_dereference(current->signal->session_keyring);
186 atomic_inc(&keyring->usage); 203 atomic_inc(&keyring->usage);
187 spin_unlock_irqrestore(&current->sighand->siglock, flags); 204 rcu_read_unlock();
188 205
189 key_link(keyring, key); 206 key_link(keyring, key);
190 key_put(keyring); 207 key_put(keyring);
@@ -220,6 +237,9 @@ static struct key *request_key_construction(struct key_type *type,
220 237
221 DECLARE_WAITQUEUE(myself, current); 238 DECLARE_WAITQUEUE(myself, current);
222 239
240 kenter("%s,%s,{%d},%s",
241 type->name, description, user->uid, callout_info);
242
223 /* see if there's such a key under construction already */ 243 /* see if there's such a key under construction already */
224 down_write(&key_construction_sem); 244 down_write(&key_construction_sem);
225 245
@@ -236,6 +256,7 @@ static struct key *request_key_construction(struct key_type *type,
236 /* see about getting userspace to construct the key */ 256 /* see about getting userspace to construct the key */
237 key = __request_key_construction(type, description, callout_info); 257 key = __request_key_construction(type, description, callout_info);
238 error: 258 error:
259 kleave(" = %p", key);
239 return key; 260 return key;
240 261
241 /* someone else has the same key under construction 262 /* someone else has the same key under construction
@@ -249,8 +270,10 @@ static struct key *request_key_construction(struct key_type *type,
249 add_wait_queue(&request_key_conswq, &myself); 270 add_wait_queue(&request_key_conswq, &myself);
250 271
251 for (;;) { 272 for (;;) {
252 set_current_state(TASK_UNINTERRUPTIBLE); 273 set_current_state(TASK_INTERRUPTIBLE);
253 if (!(ckey->flags & KEY_FLAG_USER_CONSTRUCT)) 274 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
275 break;
276 if (signal_pending(current))
254 break; 277 break;
255 schedule(); 278 schedule();
256 } 279 }
@@ -271,21 +294,83 @@ static struct key *request_key_construction(struct key_type *type,
271 294
272/*****************************************************************************/ 295/*****************************************************************************/
273/* 296/*
297 * link a freshly minted key to an appropriate destination keyring
298 */
299static void request_key_link(struct key *key, struct key *dest_keyring)
300{
301 struct task_struct *tsk = current;
302 struct key *drop = NULL;
303
304 kenter("{%d},%p", key->serial, dest_keyring);
305
306 /* find the appropriate keyring */
307 if (!dest_keyring) {
308 switch (tsk->jit_keyring) {
309 case KEY_REQKEY_DEFL_DEFAULT:
310 case KEY_REQKEY_DEFL_THREAD_KEYRING:
311 dest_keyring = tsk->thread_keyring;
312 if (dest_keyring)
313 break;
314
315 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
316 dest_keyring = tsk->signal->process_keyring;
317 if (dest_keyring)
318 break;
319
320 case KEY_REQKEY_DEFL_SESSION_KEYRING:
321 rcu_read_lock();
322 dest_keyring = key_get(
323 rcu_dereference(tsk->signal->session_keyring));
324 rcu_read_unlock();
325 drop = dest_keyring;
326
327 if (dest_keyring)
328 break;
329
330 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
331 dest_keyring = current->user->session_keyring;
332 break;
333
334 case KEY_REQKEY_DEFL_USER_KEYRING:
335 dest_keyring = current->user->uid_keyring;
336 break;
337
338 case KEY_REQKEY_DEFL_GROUP_KEYRING:
339 default:
340 BUG();
341 }
342 }
343
344 /* and attach the key to it */
345 key_link(dest_keyring, key);
346
347 key_put(drop);
348
349 kleave("");
350
351} /* end request_key_link() */
352
353/*****************************************************************************/
354/*
274 * request a key 355 * request a key
275 * - search the process's keyrings 356 * - search the process's keyrings
276 * - check the list of keys being created or updated 357 * - check the list of keys being created or updated
277 * - call out to userspace for a key if requested (supplementary info can be 358 * - call out to userspace for a key if supplementary info was provided
278 * passed) 359 * - cache the key in an appropriate keyring
279 */ 360 */
280struct key *request_key(struct key_type *type, 361struct key *request_key_and_link(struct key_type *type,
281 const char *description, 362 const char *description,
282 const char *callout_info) 363 const char *callout_info,
364 struct key *dest_keyring)
283{ 365{
284 struct key_user *user; 366 struct key_user *user;
285 struct key *key; 367 struct key *key;
286 368
369 kenter("%s,%s,%s,%p",
370 type->name, description, callout_info, dest_keyring);
371
287 /* search all the process keyrings for a key */ 372 /* search all the process keyrings for a key */
288 key = search_process_keyrings_aux(type, description, type->match); 373 key = search_process_keyrings(type, description, type->match, current);
289 374
290 if (PTR_ERR(key) == -EAGAIN) { 375 if (PTR_ERR(key) == -EAGAIN) {
291 /* the search failed, but the keyrings were searchable, so we 376 /* the search failed, but the keyrings were searchable, so we
@@ -296,12 +381,13 @@ struct key *request_key(struct key_type *type,
296 381
297 /* - get hold of the user's construction queue */ 382 /* - get hold of the user's construction queue */
298 user = key_user_lookup(current->fsuid); 383 user = key_user_lookup(current->fsuid);
299 if (!user) { 384 if (!user)
300 key = ERR_PTR(-ENOMEM); 385 goto nomem;
301 goto error; 386
302 } 387 do {
388 if (signal_pending(current))
389 goto interrupted;
303 390
304 for (;;) {
305 /* ask userspace (returns NULL if it waited on a key 391 /* ask userspace (returns NULL if it waited on a key
306 * being constructed) */ 392 * being constructed) */
307 key = request_key_construction(type, description, 393 key = request_key_construction(type, description,
@@ -311,18 +397,46 @@ struct key *request_key(struct key_type *type,
311 397
312 /* someone else made the key we want, so we need to 398 /* someone else made the key we want, so we need to
313 * search again as it might now be available to us */ 399 * search again as it might now be available to us */
314 key = search_process_keyrings_aux(type, description, 400 key = search_process_keyrings(type, description,
315 type->match); 401 type->match, current);
316 if (PTR_ERR(key) != -EAGAIN) 402
317 break; 403 } while (PTR_ERR(key) == -EAGAIN);
318 }
319 404
320 key_user_put(user); 405 key_user_put(user);
406
407 /* link the new key into the appropriate keyring */
408 if (!PTR_ERR(key))
409 request_key_link(key, dest_keyring);
321 } 410 }
322 411
323 error: 412error:
413 kleave(" = %p", key);
324 return key; 414 return key;
325 415
416nomem:
417 key = ERR_PTR(-ENOMEM);
418 goto error;
419
420interrupted:
421 key_user_put(user);
422 key = ERR_PTR(-EINTR);
423 goto error;
424
425} /* end request_key_and_link() */
426
427/*****************************************************************************/
428/*
429 * request a key
430 * - search the process's keyrings
431 * - check the list of keys being created or updated
432 * - call out to userspace for a key if supplementary info was provided
433 */
434struct key *request_key(struct key_type *type,
435 const char *description,
436 const char *callout_info)
437{
438 return request_key_and_link(type, description, callout_info, NULL);
439
326} /* end request_key() */ 440} /* end request_key() */
327 441
328EXPORT_SYMBOL(request_key); 442EXPORT_SYMBOL(request_key);
@@ -339,7 +453,8 @@ int key_validate(struct key *key)
339 if (key) { 453 if (key) {
340 /* check it's still accessible */ 454 /* check it's still accessible */
341 ret = -EKEYREVOKED; 455 ret = -EKEYREVOKED;
342 if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD)) 456 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
457 test_bit(KEY_FLAG_DEAD, &key->flags))
343 goto error; 458 goto error;
344 459
345 /* check it hasn't expired */ 460 /* check it hasn't expired */