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