xref: /linux/security/keys/request_key.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /* request_key.c: request a key from userspace
2  *
3  * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  * See Documentation/keys-request-key.txt
12  */
13 
14 #include <linux/module.h>
15 #include <linux/sched.h>
16 #include <linux/kmod.h>
17 #include <linux/err.h>
18 #include <linux/keyctl.h>
19 #include "internal.h"
20 
21 struct key_construction {
22 	struct list_head	link;	/* link in construction queue */
23 	struct key		*key;	/* key being constructed */
24 };
25 
26 /* when waiting for someone else's keys, you get added to this */
27 DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
28 
29 /*****************************************************************************/
30 /*
31  * request userspace finish the construction of a key
32  * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
33  */
34 static int call_sbin_request_key(struct key *key,
35 				 struct key *authkey,
36 				 const char *op)
37 {
38 	struct task_struct *tsk = current;
39 	key_serial_t prkey, sskey;
40 	struct key *keyring;
41 	char *argv[9], *envp[3], uid_str[12], gid_str[12];
42 	char key_str[12], keyring_str[3][12];
43 	char desc[20];
44 	int ret, i;
45 
46 	kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
47 
48 	/* allocate a new session keyring */
49 	sprintf(desc, "_req.%u", key->serial);
50 
51 	keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
52 	if (IS_ERR(keyring)) {
53 		ret = PTR_ERR(keyring);
54 		goto error_alloc;
55 	}
56 
57 	/* attach the auth key to the session keyring */
58 	ret = __key_link(keyring, authkey);
59 	if (ret < 0)
60 		goto error_link;
61 
62 	/* record the UID and GID */
63 	sprintf(uid_str, "%d", current->fsuid);
64 	sprintf(gid_str, "%d", current->fsgid);
65 
66 	/* we say which key is under construction */
67 	sprintf(key_str, "%d", key->serial);
68 
69 	/* we specify the process's default keyrings */
70 	sprintf(keyring_str[0], "%d",
71 		tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
72 
73 	prkey = 0;
74 	if (tsk->signal->process_keyring)
75 		prkey = tsk->signal->process_keyring->serial;
76 
77 	sprintf(keyring_str[1], "%d", prkey);
78 
79 	if (tsk->signal->session_keyring) {
80 		rcu_read_lock();
81 		sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
82 		rcu_read_unlock();
83 	}
84 	else {
85 		sskey = tsk->user->session_keyring->serial;
86 	}
87 
88 	sprintf(keyring_str[2], "%d", sskey);
89 
90 	/* set up a minimal environment */
91 	i = 0;
92 	envp[i++] = "HOME=/";
93 	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
94 	envp[i] = NULL;
95 
96 	/* set up the argument list */
97 	i = 0;
98 	argv[i++] = "/sbin/request-key";
99 	argv[i++] = (char *) op;
100 	argv[i++] = key_str;
101 	argv[i++] = uid_str;
102 	argv[i++] = gid_str;
103 	argv[i++] = keyring_str[0];
104 	argv[i++] = keyring_str[1];
105 	argv[i++] = keyring_str[2];
106 	argv[i] = NULL;
107 
108 	/* do it */
109 	ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
110 
111 error_link:
112 	key_put(keyring);
113 
114 error_alloc:
115 	kleave(" = %d", ret);
116 	return ret;
117 
118 } /* end call_sbin_request_key() */
119 
120 /*****************************************************************************/
121 /*
122  * call out to userspace for the key
123  * - called with the construction sem held, but the sem is dropped here
124  * - we ignore program failure and go on key status instead
125  */
126 static struct key *__request_key_construction(struct key_type *type,
127 					      const char *description,
128 					      const char *callout_info)
129 {
130 	request_key_actor_t actor;
131 	struct key_construction cons;
132 	struct timespec now;
133 	struct key *key, *authkey;
134 	int ret, negated;
135 
136 	kenter("%s,%s,%s", type->name, description, callout_info);
137 
138 	/* create a key and add it to the queue */
139 	key = key_alloc(type, description,
140 			current->fsuid, current->fsgid, KEY_POS_ALL, 0);
141 	if (IS_ERR(key))
142 		goto alloc_failed;
143 
144 	set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
145 
146 	cons.key = key;
147 	list_add_tail(&cons.link, &key->user->consq);
148 
149 	/* we drop the construction sem here on behalf of the caller */
150 	up_write(&key_construction_sem);
151 
152 	/* allocate an authorisation key */
153 	authkey = request_key_auth_new(key, callout_info);
154 	if (IS_ERR(authkey)) {
155 		ret = PTR_ERR(authkey);
156 		authkey = NULL;
157 		goto alloc_authkey_failed;
158 	}
159 
160 	/* make the call */
161 	actor = call_sbin_request_key;
162 	if (type->request_key)
163 		actor = type->request_key;
164 	ret = actor(key, authkey, "create");
165 	if (ret < 0)
166 		goto request_failed;
167 
168 	/* if the key wasn't instantiated, then we want to give an error */
169 	ret = -ENOKEY;
170 	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
171 		goto request_failed;
172 
173 	key_revoke(authkey);
174 	key_put(authkey);
175 
176 	down_write(&key_construction_sem);
177 	list_del(&cons.link);
178 	up_write(&key_construction_sem);
179 
180 	/* also give an error if the key was negatively instantiated */
181 check_not_negative:
182 	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
183 		key_put(key);
184 		key = ERR_PTR(-ENOKEY);
185 	}
186 
187 out:
188 	kleave(" = %p", key);
189 	return key;
190 
191 request_failed:
192 	key_revoke(authkey);
193 	key_put(authkey);
194 
195 alloc_authkey_failed:
196 	/* it wasn't instantiated
197 	 * - remove from construction queue
198 	 * - mark the key as dead
199 	 */
200 	negated = 0;
201 	down_write(&key_construction_sem);
202 
203 	list_del(&cons.link);
204 
205 	/* check it didn't get instantiated between the check and the down */
206 	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
207 		set_bit(KEY_FLAG_NEGATIVE, &key->flags);
208 		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
209 		negated = 1;
210 	}
211 
212 	clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
213 
214 	up_write(&key_construction_sem);
215 
216 	if (!negated)
217 		goto check_not_negative; /* surprisingly, the key got
218 					  * instantiated */
219 
220 	/* set the timeout and store in the session keyring if we can */
221 	now = current_kernel_time();
222 	key->expiry = now.tv_sec + key_negative_timeout;
223 
224 	if (current->signal->session_keyring) {
225 		struct key *keyring;
226 
227 		rcu_read_lock();
228 		keyring = rcu_dereference(current->signal->session_keyring);
229 		atomic_inc(&keyring->usage);
230 		rcu_read_unlock();
231 
232 		key_link(keyring, key);
233 		key_put(keyring);
234 	}
235 
236 	key_put(key);
237 
238 	/* notify anyone who was waiting */
239 	wake_up_all(&request_key_conswq);
240 
241 	key = ERR_PTR(ret);
242 	goto out;
243 
244 alloc_failed:
245 	up_write(&key_construction_sem);
246 	goto out;
247 
248 } /* end __request_key_construction() */
249 
250 /*****************************************************************************/
251 /*
252  * call out to userspace to request the key
253  * - we check the construction queue first to see if an appropriate key is
254  *   already being constructed by userspace
255  */
256 static struct key *request_key_construction(struct key_type *type,
257 					    const char *description,
258 					    struct key_user *user,
259 					    const char *callout_info)
260 {
261 	struct key_construction *pcons;
262 	struct key *key, *ckey;
263 
264 	DECLARE_WAITQUEUE(myself, current);
265 
266 	kenter("%s,%s,{%d},%s",
267 	       type->name, description, user->uid, callout_info);
268 
269 	/* see if there's such a key under construction already */
270 	down_write(&key_construction_sem);
271 
272 	list_for_each_entry(pcons, &user->consq, link) {
273 		ckey = pcons->key;
274 
275 		if (ckey->type != type)
276 			continue;
277 
278 		if (type->match(ckey, description))
279 			goto found_key_under_construction;
280 	}
281 
282 	/* see about getting userspace to construct the key */
283 	key = __request_key_construction(type, description, callout_info);
284  error:
285 	kleave(" = %p", key);
286 	return key;
287 
288 	/* someone else has the same key under construction
289 	 * - we want to keep an eye on their key
290 	 */
291  found_key_under_construction:
292 	atomic_inc(&ckey->usage);
293 	up_write(&key_construction_sem);
294 
295 	/* wait for the key to be completed one way or another */
296 	add_wait_queue(&request_key_conswq, &myself);
297 
298 	for (;;) {
299 		set_current_state(TASK_INTERRUPTIBLE);
300 		if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
301 			break;
302 		if (signal_pending(current))
303 			break;
304 		schedule();
305 	}
306 
307 	set_current_state(TASK_RUNNING);
308 	remove_wait_queue(&request_key_conswq, &myself);
309 
310 	/* we'll need to search this process's keyrings to see if the key is
311 	 * now there since we can't automatically assume it's also available
312 	 * there */
313 	key_put(ckey);
314 	ckey = NULL;
315 
316 	key = NULL; /* request a retry */
317 	goto error;
318 
319 } /* end request_key_construction() */
320 
321 /*****************************************************************************/
322 /*
323  * link a freshly minted key to an appropriate destination keyring
324  */
325 static void request_key_link(struct key *key, struct key *dest_keyring)
326 {
327 	struct task_struct *tsk = current;
328 	struct key *drop = NULL;
329 
330 	kenter("{%d},%p", key->serial, dest_keyring);
331 
332 	/* find the appropriate keyring */
333 	if (!dest_keyring) {
334 		switch (tsk->jit_keyring) {
335 		case KEY_REQKEY_DEFL_DEFAULT:
336 		case KEY_REQKEY_DEFL_THREAD_KEYRING:
337 			dest_keyring = tsk->thread_keyring;
338 			if (dest_keyring)
339 				break;
340 
341 		case KEY_REQKEY_DEFL_PROCESS_KEYRING:
342 			dest_keyring = tsk->signal->process_keyring;
343 			if (dest_keyring)
344 				break;
345 
346 		case KEY_REQKEY_DEFL_SESSION_KEYRING:
347 			rcu_read_lock();
348 			dest_keyring = key_get(
349 				rcu_dereference(tsk->signal->session_keyring));
350 			rcu_read_unlock();
351 			drop = dest_keyring;
352 
353 			if (dest_keyring)
354 				break;
355 
356 		case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
357 			dest_keyring = current->user->session_keyring;
358 			break;
359 
360 		case KEY_REQKEY_DEFL_USER_KEYRING:
361 			dest_keyring = current->user->uid_keyring;
362 			break;
363 
364 		case KEY_REQKEY_DEFL_GROUP_KEYRING:
365 		default:
366 			BUG();
367 		}
368 	}
369 
370 	/* and attach the key to it */
371 	key_link(dest_keyring, key);
372 
373 	key_put(drop);
374 
375 	kleave("");
376 
377 } /* end request_key_link() */
378 
379 /*****************************************************************************/
380 /*
381  * request a key
382  * - search the process's keyrings
383  * - check the list of keys being created or updated
384  * - call out to userspace for a key if supplementary info was provided
385  * - cache the key in an appropriate keyring
386  */
387 struct key *request_key_and_link(struct key_type *type,
388 				 const char *description,
389 				 const char *callout_info,
390 				 struct key *dest_keyring)
391 {
392 	struct key_user *user;
393 	struct key *key;
394 	key_ref_t key_ref;
395 
396 	kenter("%s,%s,%s,%p",
397 	       type->name, description, callout_info, dest_keyring);
398 
399 	/* search all the process keyrings for a key */
400 	key_ref = search_process_keyrings(type, description, type->match,
401 					  current);
402 
403 	kdebug("search 1: %p", key_ref);
404 
405 	if (!IS_ERR(key_ref)) {
406 		key = key_ref_to_ptr(key_ref);
407 	}
408 	else if (PTR_ERR(key_ref) != -EAGAIN) {
409 		key = ERR_PTR(PTR_ERR(key_ref));
410 	}
411 	else  {
412 		/* the search failed, but the keyrings were searchable, so we
413 		 * should consult userspace if we can */
414 		key = ERR_PTR(-ENOKEY);
415 		if (!callout_info)
416 			goto error;
417 
418 		/* - get hold of the user's construction queue */
419 		user = key_user_lookup(current->fsuid);
420 		if (!user)
421 			goto nomem;
422 
423 		for (;;) {
424 			if (signal_pending(current))
425 				goto interrupted;
426 
427 			/* ask userspace (returns NULL if it waited on a key
428 			 * being constructed) */
429 			key = request_key_construction(type, description,
430 						       user, callout_info);
431 			if (key)
432 				break;
433 
434 			/* someone else made the key we want, so we need to
435 			 * search again as it might now be available to us */
436 			key_ref = search_process_keyrings(type, description,
437 							  type->match,
438 							  current);
439 
440 			kdebug("search 2: %p", key_ref);
441 
442 			if (!IS_ERR(key_ref)) {
443 				key = key_ref_to_ptr(key_ref);
444 				break;
445 			}
446 
447 			if (PTR_ERR(key_ref) != -EAGAIN) {
448 				key = ERR_PTR(PTR_ERR(key_ref));
449 				break;
450 			}
451 		}
452 
453 		key_user_put(user);
454 
455 		/* link the new key into the appropriate keyring */
456 		if (!IS_ERR(key))
457 			request_key_link(key, dest_keyring);
458 	}
459 
460 error:
461 	kleave(" = %p", key);
462 	return key;
463 
464 nomem:
465 	key = ERR_PTR(-ENOMEM);
466 	goto error;
467 
468 interrupted:
469 	key_user_put(user);
470 	key = ERR_PTR(-EINTR);
471 	goto error;
472 
473 } /* end request_key_and_link() */
474 
475 /*****************************************************************************/
476 /*
477  * request a key
478  * - search the process's keyrings
479  * - check the list of keys being created or updated
480  * - call out to userspace for a key if supplementary info was provided
481  */
482 struct key *request_key(struct key_type *type,
483 			const char *description,
484 			const char *callout_info)
485 {
486 	return request_key_and_link(type, description, callout_info, NULL);
487 
488 } /* end request_key() */
489 
490 EXPORT_SYMBOL(request_key);
491