• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Management of a process's keyrings
2  *
3  * Copyright (C) 2004-2005, 2008 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 
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/sched.h>
15 #include <linux/slab.h>
16 #include <linux/keyctl.h>
17 #include <linux/fs.h>
18 #include <linux/err.h>
19 #include <linux/mutex.h>
20 #include <asm/uaccess.h>
21 #include "internal.h"
22 
23 /* session keyring create vs join semaphore */
24 static DEFINE_MUTEX(key_session_mutex);
25 
26 /* user keyring creation semaphore */
27 static DEFINE_MUTEX(key_user_keyring_mutex);
28 
29 /* the root user's tracking struct */
30 struct key_user root_key_user = {
31 	.usage		= ATOMIC_INIT(3),
32 	.cons_lock	= __MUTEX_INITIALIZER(root_key_user.cons_lock),
33 	.lock		= __SPIN_LOCK_UNLOCKED(root_key_user.lock),
34 	.nkeys		= ATOMIC_INIT(2),
35 	.nikeys		= ATOMIC_INIT(2),
36 	.uid		= 0,
37 };
38 
39 /*****************************************************************************/
40 /*
41  * install user and user session keyrings for a particular UID
42  */
install_user_keyrings(void)43 int install_user_keyrings(void)
44 {
45 	struct user_struct *user;
46 	const struct cred *cred;
47 	struct key *uid_keyring, *session_keyring;
48 	char buf[20];
49 	int ret;
50 
51 	cred = current_cred();
52 	user = cred->user;
53 
54 	kenter("%p{%u}", user, user->uid);
55 
56 	if (user->uid_keyring) {
57 		kleave(" = 0 [exist]");
58 		return 0;
59 	}
60 
61 	mutex_lock(&key_user_keyring_mutex);
62 	ret = 0;
63 
64 	if (!user->uid_keyring) {
65 		/* get the UID-specific keyring
66 		 * - there may be one in existence already as it may have been
67 		 *   pinned by a session, but the user_struct pointing to it
68 		 *   may have been destroyed by setuid */
69 		sprintf(buf, "_uid.%u", user->uid);
70 
71 		uid_keyring = find_keyring_by_name(buf, true);
72 		if (IS_ERR(uid_keyring)) {
73 			uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
74 						    cred, KEY_ALLOC_IN_QUOTA,
75 						    NULL);
76 			if (IS_ERR(uid_keyring)) {
77 				ret = PTR_ERR(uid_keyring);
78 				goto error;
79 			}
80 		}
81 
82 		/* get a default session keyring (which might also exist
83 		 * already) */
84 		sprintf(buf, "_uid_ses.%u", user->uid);
85 
86 		session_keyring = find_keyring_by_name(buf, true);
87 		if (IS_ERR(session_keyring)) {
88 			session_keyring =
89 				keyring_alloc(buf, user->uid, (gid_t) -1,
90 					      cred, KEY_ALLOC_IN_QUOTA, NULL);
91 			if (IS_ERR(session_keyring)) {
92 				ret = PTR_ERR(session_keyring);
93 				goto error_release;
94 			}
95 
96 			/* we install a link from the user session keyring to
97 			 * the user keyring */
98 			ret = key_link(session_keyring, uid_keyring);
99 			if (ret < 0)
100 				goto error_release_both;
101 		}
102 
103 		/* install the keyrings */
104 		user->uid_keyring = uid_keyring;
105 		user->session_keyring = session_keyring;
106 	}
107 
108 	mutex_unlock(&key_user_keyring_mutex);
109 	kleave(" = 0");
110 	return 0;
111 
112 error_release_both:
113 	key_put(session_keyring);
114 error_release:
115 	key_put(uid_keyring);
116 error:
117 	mutex_unlock(&key_user_keyring_mutex);
118 	kleave(" = %d", ret);
119 	return ret;
120 }
121 
122 /*
123  * install a fresh thread keyring directly to new credentials
124  */
install_thread_keyring_to_cred(struct cred * new)125 int install_thread_keyring_to_cred(struct cred *new)
126 {
127 	struct key *keyring;
128 
129 	keyring = keyring_alloc("_tid", new->uid, new->gid, new,
130 				KEY_ALLOC_QUOTA_OVERRUN, NULL);
131 	if (IS_ERR(keyring))
132 		return PTR_ERR(keyring);
133 
134 	new->thread_keyring = keyring;
135 	return 0;
136 }
137 
138 /*
139  * install a fresh thread keyring, discarding the old one
140  */
install_thread_keyring(void)141 static int install_thread_keyring(void)
142 {
143 	struct cred *new;
144 	int ret;
145 
146 	new = prepare_creds();
147 	if (!new)
148 		return -ENOMEM;
149 
150 	BUG_ON(new->thread_keyring);
151 
152 	ret = install_thread_keyring_to_cred(new);
153 	if (ret < 0) {
154 		abort_creds(new);
155 		return ret;
156 	}
157 
158 	return commit_creds(new);
159 }
160 
161 /*
162  * install a process keyring directly to a credentials struct
163  * - returns -EEXIST if there was already a process keyring, 0 if one installed,
164  *   and other -ve on any other error
165  */
install_process_keyring_to_cred(struct cred * new)166 int install_process_keyring_to_cred(struct cred *new)
167 {
168 	struct key *keyring;
169 	int ret;
170 
171 	if (new->tgcred->process_keyring)
172 		return -EEXIST;
173 
174 	keyring = keyring_alloc("_pid", new->uid, new->gid,
175 				new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
176 	if (IS_ERR(keyring))
177 		return PTR_ERR(keyring);
178 
179 	spin_lock_irq(&new->tgcred->lock);
180 	if (!new->tgcred->process_keyring) {
181 		new->tgcred->process_keyring = keyring;
182 		keyring = NULL;
183 		ret = 0;
184 	} else {
185 		ret = -EEXIST;
186 	}
187 	spin_unlock_irq(&new->tgcred->lock);
188 	key_put(keyring);
189 	return ret;
190 }
191 
192 /*
193  * make sure a process keyring is installed
194  * - we
195  */
install_process_keyring(void)196 static int install_process_keyring(void)
197 {
198 	struct cred *new;
199 	int ret;
200 
201 	new = prepare_creds();
202 	if (!new)
203 		return -ENOMEM;
204 
205 	ret = install_process_keyring_to_cred(new);
206 	if (ret < 0) {
207 		abort_creds(new);
208 		return ret != -EEXIST ?: 0;
209 	}
210 
211 	return commit_creds(new);
212 }
213 
214 /*
215  * install a session keyring directly to a credentials struct
216  */
install_session_keyring_to_cred(struct cred * cred,struct key * keyring)217 static int install_session_keyring_to_cred(struct cred *cred,
218 					   struct key *keyring)
219 {
220 	unsigned long flags;
221 	struct key *old;
222 
223 	might_sleep();
224 
225 	/* create an empty session keyring */
226 	if (!keyring) {
227 		flags = KEY_ALLOC_QUOTA_OVERRUN;
228 		if (cred->tgcred->session_keyring)
229 			flags = KEY_ALLOC_IN_QUOTA;
230 
231 		keyring = keyring_alloc("_ses", cred->uid, cred->gid,
232 					cred, flags, NULL);
233 		if (IS_ERR(keyring))
234 			return PTR_ERR(keyring);
235 	} else {
236 		atomic_inc(&keyring->usage);
237 	}
238 
239 	/* install the keyring */
240 	spin_lock_irq(&cred->tgcred->lock);
241 	old = cred->tgcred->session_keyring;
242 	rcu_assign_pointer(cred->tgcred->session_keyring, keyring);
243 	spin_unlock_irq(&cred->tgcred->lock);
244 
245 	/* we're using RCU on the pointer, but there's no point synchronising
246 	 * on it if it didn't previously point to anything */
247 	if (old) {
248 		synchronize_rcu();
249 		key_put(old);
250 	}
251 
252 	return 0;
253 }
254 
255 /*
256  * install a session keyring, discarding the old one
257  * - if a keyring is not supplied, an empty one is invented
258  */
install_session_keyring(struct key * keyring)259 static int install_session_keyring(struct key *keyring)
260 {
261 	struct cred *new;
262 	int ret;
263 
264 	new = prepare_creds();
265 	if (!new)
266 		return -ENOMEM;
267 
268 	ret = install_session_keyring_to_cred(new, NULL);
269 	if (ret < 0) {
270 		abort_creds(new);
271 		return ret;
272 	}
273 
274 	return commit_creds(new);
275 }
276 
277 /*****************************************************************************/
278 /*
279  * the filesystem user ID changed
280  */
key_fsuid_changed(struct task_struct * tsk)281 void key_fsuid_changed(struct task_struct *tsk)
282 {
283 	/* update the ownership of the thread keyring */
284 	BUG_ON(!tsk->cred);
285 	if (tsk->cred->thread_keyring) {
286 		down_write(&tsk->cred->thread_keyring->sem);
287 		tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
288 		up_write(&tsk->cred->thread_keyring->sem);
289 	}
290 
291 } /* end key_fsuid_changed() */
292 
293 /*****************************************************************************/
294 /*
295  * the filesystem group ID changed
296  */
key_fsgid_changed(struct task_struct * tsk)297 void key_fsgid_changed(struct task_struct *tsk)
298 {
299 	/* update the ownership of the thread keyring */
300 	BUG_ON(!tsk->cred);
301 	if (tsk->cred->thread_keyring) {
302 		down_write(&tsk->cred->thread_keyring->sem);
303 		tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
304 		up_write(&tsk->cred->thread_keyring->sem);
305 	}
306 
307 } /* end key_fsgid_changed() */
308 
309 /*****************************************************************************/
310 /*
311  * search the process keyrings for the first matching key
312  * - we use the supplied match function to see if the description (or other
313  *   feature of interest) matches
314  * - we return -EAGAIN if we didn't find any matching key
315  * - we return -ENOKEY if we found only negative matching keys
316  */
search_process_keyrings(struct key_type * type,const void * description,key_match_func_t match,const struct cred * cred)317 key_ref_t search_process_keyrings(struct key_type *type,
318 				  const void *description,
319 				  key_match_func_t match,
320 				  const struct cred *cred)
321 {
322 	struct request_key_auth *rka;
323 	key_ref_t key_ref, ret, err;
324 
325 	might_sleep();
326 
327 	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
328 	 * searchable, but we failed to find a key or we found a negative key;
329 	 * otherwise we want to return a sample error (probably -EACCES) if
330 	 * none of the keyrings were searchable
331 	 *
332 	 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
333 	 */
334 	key_ref = NULL;
335 	ret = NULL;
336 	err = ERR_PTR(-EAGAIN);
337 
338 	/* search the thread keyring first */
339 	if (cred->thread_keyring) {
340 		key_ref = keyring_search_aux(
341 			make_key_ref(cred->thread_keyring, 1),
342 			cred, type, description, match);
343 		if (!IS_ERR(key_ref))
344 			goto found;
345 
346 		switch (PTR_ERR(key_ref)) {
347 		case -EAGAIN: /* no key */
348 			if (ret)
349 				break;
350 		case -ENOKEY: /* negative key */
351 			ret = key_ref;
352 			break;
353 		default:
354 			err = key_ref;
355 			break;
356 		}
357 	}
358 
359 	/* search the process keyring second */
360 	if (cred->tgcred->process_keyring) {
361 		key_ref = keyring_search_aux(
362 			make_key_ref(cred->tgcred->process_keyring, 1),
363 			cred, type, description, match);
364 		if (!IS_ERR(key_ref))
365 			goto found;
366 
367 		switch (PTR_ERR(key_ref)) {
368 		case -EAGAIN: /* no key */
369 			if (ret)
370 				break;
371 		case -ENOKEY: /* negative key */
372 			ret = key_ref;
373 			break;
374 		default:
375 			err = key_ref;
376 			break;
377 		}
378 	}
379 
380 	/* search the session keyring */
381 	if (cred->tgcred->session_keyring) {
382 		rcu_read_lock();
383 		key_ref = keyring_search_aux(
384 			make_key_ref(rcu_dereference(
385 					     cred->tgcred->session_keyring),
386 				     1),
387 			cred, type, description, match);
388 		rcu_read_unlock();
389 
390 		if (!IS_ERR(key_ref))
391 			goto found;
392 
393 		switch (PTR_ERR(key_ref)) {
394 		case -EAGAIN: /* no key */
395 			if (ret)
396 				break;
397 		case -ENOKEY: /* negative key */
398 			ret = key_ref;
399 			break;
400 		default:
401 			err = key_ref;
402 			break;
403 		}
404 	}
405 	/* or search the user-session keyring */
406 	else if (cred->user->session_keyring) {
407 		key_ref = keyring_search_aux(
408 			make_key_ref(cred->user->session_keyring, 1),
409 			cred, type, description, match);
410 		if (!IS_ERR(key_ref))
411 			goto found;
412 
413 		switch (PTR_ERR(key_ref)) {
414 		case -EAGAIN: /* no key */
415 			if (ret)
416 				break;
417 		case -ENOKEY: /* negative key */
418 			ret = key_ref;
419 			break;
420 		default:
421 			err = key_ref;
422 			break;
423 		}
424 	}
425 
426 	/* if this process has an instantiation authorisation key, then we also
427 	 * search the keyrings of the process mentioned there
428 	 * - we don't permit access to request_key auth keys via this method
429 	 */
430 	if (cred->request_key_auth &&
431 	    cred == current_cred() &&
432 	    type != &key_type_request_key_auth
433 	    ) {
434 		/* defend against the auth key being revoked */
435 		down_read(&cred->request_key_auth->sem);
436 
437 		if (key_validate(cred->request_key_auth) == 0) {
438 			rka = cred->request_key_auth->payload.data;
439 
440 			key_ref = search_process_keyrings(type, description,
441 							  match, rka->cred);
442 
443 			up_read(&cred->request_key_auth->sem);
444 
445 			if (!IS_ERR(key_ref))
446 				goto found;
447 
448 			switch (PTR_ERR(key_ref)) {
449 			case -EAGAIN: /* no key */
450 				if (ret)
451 					break;
452 			case -ENOKEY: /* negative key */
453 				ret = key_ref;
454 				break;
455 			default:
456 				err = key_ref;
457 				break;
458 			}
459 		} else {
460 			up_read(&cred->request_key_auth->sem);
461 		}
462 	}
463 
464 	/* no key - decide on the error we're going to go for */
465 	key_ref = ret ? ret : err;
466 
467 found:
468 	return key_ref;
469 
470 } /* end search_process_keyrings() */
471 
472 /*****************************************************************************/
473 /*
474  * see if the key we're looking at is the target key
475  */
lookup_user_key_possessed(const struct key * key,const void * target)476 static int lookup_user_key_possessed(const struct key *key, const void *target)
477 {
478 	return key == target;
479 
480 } /* end lookup_user_key_possessed() */
481 
482 /*****************************************************************************/
483 /*
484  * lookup a key given a key ID from userspace with a given permissions mask
485  * - don't create special keyrings unless so requested
486  * - partially constructed keys aren't found unless requested
487  */
lookup_user_key(key_serial_t id,int create,int partial,key_perm_t perm)488 key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
489 			  key_perm_t perm)
490 {
491 	struct request_key_auth *rka;
492 	const struct cred *cred;
493 	struct key *key;
494 	key_ref_t key_ref, skey_ref;
495 	int ret;
496 
497 try_again:
498 	cred = get_current_cred();
499 	key_ref = ERR_PTR(-ENOKEY);
500 
501 	switch (id) {
502 	case KEY_SPEC_THREAD_KEYRING:
503 		if (!cred->thread_keyring) {
504 			if (!create)
505 				goto error;
506 
507 			ret = install_thread_keyring();
508 			if (ret < 0) {
509 				key = ERR_PTR(ret);
510 				goto error;
511 			}
512 			goto reget_creds;
513 		}
514 
515 		key = cred->thread_keyring;
516 		atomic_inc(&key->usage);
517 		key_ref = make_key_ref(key, 1);
518 		break;
519 
520 	case KEY_SPEC_PROCESS_KEYRING:
521 		if (!cred->tgcred->process_keyring) {
522 			if (!create)
523 				goto error;
524 
525 			ret = install_process_keyring();
526 			if (ret < 0) {
527 				key = ERR_PTR(ret);
528 				goto error;
529 			}
530 			goto reget_creds;
531 		}
532 
533 		key = cred->tgcred->process_keyring;
534 		atomic_inc(&key->usage);
535 		key_ref = make_key_ref(key, 1);
536 		break;
537 
538 	case KEY_SPEC_SESSION_KEYRING:
539 		if (!cred->tgcred->session_keyring) {
540 			/* always install a session keyring upon access if one
541 			 * doesn't exist yet */
542 			ret = install_user_keyrings();
543 			if (ret < 0)
544 				goto error;
545 			ret = install_session_keyring(
546 				cred->user->session_keyring);
547 
548 			if (ret < 0)
549 				goto error;
550 			goto reget_creds;
551 		}
552 
553 		rcu_read_lock();
554 		key = rcu_dereference(cred->tgcred->session_keyring);
555 		atomic_inc(&key->usage);
556 		rcu_read_unlock();
557 		key_ref = make_key_ref(key, 1);
558 		break;
559 
560 	case KEY_SPEC_USER_KEYRING:
561 		if (!cred->user->uid_keyring) {
562 			ret = install_user_keyrings();
563 			if (ret < 0)
564 				goto error;
565 		}
566 
567 		key = cred->user->uid_keyring;
568 		atomic_inc(&key->usage);
569 		key_ref = make_key_ref(key, 1);
570 		break;
571 
572 	case KEY_SPEC_USER_SESSION_KEYRING:
573 		if (!cred->user->session_keyring) {
574 			ret = install_user_keyrings();
575 			if (ret < 0)
576 				goto error;
577 		}
578 
579 		key = cred->user->session_keyring;
580 		atomic_inc(&key->usage);
581 		key_ref = make_key_ref(key, 1);
582 		break;
583 
584 	case KEY_SPEC_GROUP_KEYRING:
585 		/* group keyrings are not yet supported */
586 		key = ERR_PTR(-EINVAL);
587 		goto error;
588 
589 	case KEY_SPEC_REQKEY_AUTH_KEY:
590 		key = cred->request_key_auth;
591 		if (!key)
592 			goto error;
593 
594 		atomic_inc(&key->usage);
595 		key_ref = make_key_ref(key, 1);
596 		break;
597 
598 	case KEY_SPEC_REQUESTOR_KEYRING:
599 		if (!cred->request_key_auth)
600 			goto error;
601 
602 		down_read(&cred->request_key_auth->sem);
603 		if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) {
604 			key_ref = ERR_PTR(-EKEYREVOKED);
605 			key = NULL;
606 		} else {
607 			rka = cred->request_key_auth->payload.data;
608 			key = rka->dest_keyring;
609 			atomic_inc(&key->usage);
610 		}
611 		up_read(&cred->request_key_auth->sem);
612 		if (!key)
613 			goto error;
614 		key_ref = make_key_ref(key, 1);
615 		break;
616 
617 	default:
618 		key_ref = ERR_PTR(-EINVAL);
619 		if (id < 1)
620 			goto error;
621 
622 		key = key_lookup(id);
623 		if (IS_ERR(key)) {
624 			key_ref = ERR_CAST(key);
625 			goto error;
626 		}
627 
628 		key_ref = make_key_ref(key, 0);
629 
630 		/* check to see if we possess the key */
631 		skey_ref = search_process_keyrings(key->type, key,
632 						   lookup_user_key_possessed,
633 						   cred);
634 
635 		if (!IS_ERR(skey_ref)) {
636 			key_put(key);
637 			key_ref = skey_ref;
638 		}
639 
640 		break;
641 	}
642 
643 	if (!partial) {
644 		ret = wait_for_key_construction(key, true);
645 		switch (ret) {
646 		case -ERESTARTSYS:
647 			goto invalid_key;
648 		default:
649 			if (perm)
650 				goto invalid_key;
651 		case 0:
652 			break;
653 		}
654 	} else if (perm) {
655 		ret = key_validate(key);
656 		if (ret < 0)
657 			goto invalid_key;
658 	}
659 
660 	ret = -EIO;
661 	if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
662 		goto invalid_key;
663 
664 	/* check the permissions */
665 	ret = key_task_permission(key_ref, cred, perm);
666 	if (ret < 0)
667 		goto invalid_key;
668 
669 error:
670 	put_cred(cred);
671 	return key_ref;
672 
673 invalid_key:
674 	key_ref_put(key_ref);
675 	key_ref = ERR_PTR(ret);
676 	goto error;
677 
678 	/* if we attempted to install a keyring, then it may have caused new
679 	 * creds to be installed */
680 reget_creds:
681 	put_cred(cred);
682 	goto try_again;
683 
684 } /* end lookup_user_key() */
685 
686 /*****************************************************************************/
687 /*
688  * join the named keyring as the session keyring if possible, or attempt to
689  * create a new one of that name if not
690  * - if the name is NULL, an empty anonymous keyring is installed instead
691  * - named session keyring joining is done with a semaphore held
692  */
join_session_keyring(const char * name)693 long join_session_keyring(const char *name)
694 {
695 	const struct cred *old;
696 	struct cred *new;
697 	struct key *keyring;
698 	long ret, serial;
699 
700 	/* only permit this if there's a single thread in the thread group -
701 	 * this avoids us having to adjust the creds on all threads and risking
702 	 * ENOMEM */
703 	if (!is_single_threaded(current))
704 		return -EMLINK;
705 
706 	new = prepare_creds();
707 	if (!new)
708 		return -ENOMEM;
709 	old = current_cred();
710 
711 	/* if no name is provided, install an anonymous keyring */
712 	if (!name) {
713 		ret = install_session_keyring_to_cred(new, NULL);
714 		if (ret < 0)
715 			goto error;
716 
717 		serial = new->tgcred->session_keyring->serial;
718 		ret = commit_creds(new);
719 		if (ret == 0)
720 			ret = serial;
721 		goto okay;
722 	}
723 
724 	/* allow the user to join or create a named keyring */
725 	mutex_lock(&key_session_mutex);
726 
727 	/* look for an existing keyring of this name */
728 	keyring = find_keyring_by_name(name, false);
729 	if (PTR_ERR(keyring) == -ENOKEY) {
730 		/* not found - try and create a new one */
731 		keyring = keyring_alloc(name, old->uid, old->gid, old,
732 					KEY_ALLOC_IN_QUOTA, NULL);
733 		if (IS_ERR(keyring)) {
734 			ret = PTR_ERR(keyring);
735 			goto error2;
736 		}
737 	} else if (IS_ERR(keyring)) {
738 		ret = PTR_ERR(keyring);
739 		goto error2;
740 	}
741 
742 	/* we've got a keyring - now to install it */
743 	ret = install_session_keyring_to_cred(new, keyring);
744 	if (ret < 0)
745 		goto error2;
746 
747 	commit_creds(new);
748 	mutex_unlock(&key_session_mutex);
749 
750 	ret = keyring->serial;
751 	key_put(keyring);
752 okay:
753 	return ret;
754 
755 error2:
756 	mutex_unlock(&key_session_mutex);
757 error:
758 	abort_creds(new);
759 	return ret;
760 }
761