xref: /openbmc/linux/security/keys/process_keys.c (revision 1da177e4)
1 /* process_keys.c: management of a process's keyrings
2  *
3  * Copyright (C) 2004 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 <asm/uaccess.h>
20 #include "internal.h"
21 
22 /* session keyring create vs join semaphore */
23 static DECLARE_MUTEX(key_session_sem);
24 
25 /* the root user's tracking struct */
26 struct key_user root_key_user = {
27 	.usage		= ATOMIC_INIT(3),
28 	.consq		= LIST_HEAD_INIT(root_key_user.consq),
29 	.lock		= SPIN_LOCK_UNLOCKED,
30 	.nkeys		= ATOMIC_INIT(2),
31 	.nikeys		= ATOMIC_INIT(2),
32 	.uid		= 0,
33 };
34 
35 /* the root user's UID keyring */
36 struct key root_user_keyring = {
37 	.usage		= ATOMIC_INIT(1),
38 	.serial		= 2,
39 	.type		= &key_type_keyring,
40 	.user		= &root_key_user,
41 	.lock		= RW_LOCK_UNLOCKED,
42 	.sem		= __RWSEM_INITIALIZER(root_user_keyring.sem),
43 	.perm		= KEY_USR_ALL,
44 	.flags		= KEY_FLAG_INSTANTIATED,
45 	.description	= "_uid.0",
46 #ifdef KEY_DEBUGGING
47 	.magic		= KEY_DEBUG_MAGIC,
48 #endif
49 };
50 
51 /* the root user's default session keyring */
52 struct key root_session_keyring = {
53 	.usage		= ATOMIC_INIT(1),
54 	.serial		= 1,
55 	.type		= &key_type_keyring,
56 	.user		= &root_key_user,
57 	.lock		= RW_LOCK_UNLOCKED,
58 	.sem		= __RWSEM_INITIALIZER(root_session_keyring.sem),
59 	.perm		= KEY_USR_ALL,
60 	.flags		= KEY_FLAG_INSTANTIATED,
61 	.description	= "_uid_ses.0",
62 #ifdef KEY_DEBUGGING
63 	.magic		= KEY_DEBUG_MAGIC,
64 #endif
65 };
66 
67 /*****************************************************************************/
68 /*
69  * allocate the keyrings to be associated with a UID
70  */
71 int alloc_uid_keyring(struct user_struct *user)
72 {
73 	struct key *uid_keyring, *session_keyring;
74 	char buf[20];
75 	int ret;
76 
77 	/* concoct a default session keyring */
78 	sprintf(buf, "_uid_ses.%u", user->uid);
79 
80 	session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL);
81 	if (IS_ERR(session_keyring)) {
82 		ret = PTR_ERR(session_keyring);
83 		goto error;
84 	}
85 
86 	/* and a UID specific keyring, pointed to by the default session
87 	 * keyring */
88 	sprintf(buf, "_uid.%u", user->uid);
89 
90 	uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0,
91 				    session_keyring);
92 	if (IS_ERR(uid_keyring)) {
93 		key_put(session_keyring);
94 		ret = PTR_ERR(uid_keyring);
95 		goto error;
96 	}
97 
98 	/* install the keyrings */
99 	user->uid_keyring = uid_keyring;
100 	user->session_keyring = session_keyring;
101 	ret = 0;
102 
103  error:
104 	return ret;
105 
106 } /* end alloc_uid_keyring() */
107 
108 /*****************************************************************************/
109 /*
110  * deal with the UID changing
111  */
112 void switch_uid_keyring(struct user_struct *new_user)
113 {
114 #if 0 /* do nothing for now */
115 	struct key *old;
116 
117 	/* switch to the new user's session keyring if we were running under
118 	 * root's default session keyring */
119 	if (new_user->uid != 0 &&
120 	    current->session_keyring == &root_session_keyring
121 	    ) {
122 		atomic_inc(&new_user->session_keyring->usage);
123 
124 		task_lock(current);
125 		old = current->session_keyring;
126 		current->session_keyring = new_user->session_keyring;
127 		task_unlock(current);
128 
129 		key_put(old);
130 	}
131 #endif
132 
133 } /* end switch_uid_keyring() */
134 
135 /*****************************************************************************/
136 /*
137  * install a fresh thread keyring, discarding the old one
138  */
139 int install_thread_keyring(struct task_struct *tsk)
140 {
141 	struct key *keyring, *old;
142 	char buf[20];
143 	int ret;
144 
145 	sprintf(buf, "_tid.%u", tsk->pid);
146 
147 	keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
148 	if (IS_ERR(keyring)) {
149 		ret = PTR_ERR(keyring);
150 		goto error;
151 	}
152 
153 	task_lock(tsk);
154 	old = tsk->thread_keyring;
155 	tsk->thread_keyring = keyring;
156 	task_unlock(tsk);
157 
158 	ret = 0;
159 
160 	key_put(old);
161  error:
162 	return ret;
163 
164 } /* end install_thread_keyring() */
165 
166 /*****************************************************************************/
167 /*
168  * make sure a process keyring is installed
169  */
170 static int install_process_keyring(struct task_struct *tsk)
171 {
172 	unsigned long flags;
173 	struct key *keyring;
174 	char buf[20];
175 	int ret;
176 
177 	if (!tsk->signal->process_keyring) {
178 		sprintf(buf, "_pid.%u", tsk->tgid);
179 
180 		keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
181 		if (IS_ERR(keyring)) {
182 			ret = PTR_ERR(keyring);
183 			goto error;
184 		}
185 
186 		/* attach or swap keyrings */
187 		spin_lock_irqsave(&tsk->sighand->siglock, flags);
188 		if (!tsk->signal->process_keyring) {
189 			tsk->signal->process_keyring = keyring;
190 			keyring = NULL;
191 		}
192 		spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
193 
194 		key_put(keyring);
195 	}
196 
197 	ret = 0;
198  error:
199 	return ret;
200 
201 } /* end install_process_keyring() */
202 
203 /*****************************************************************************/
204 /*
205  * install a session keyring, discarding the old one
206  * - if a keyring is not supplied, an empty one is invented
207  */
208 static int install_session_keyring(struct task_struct *tsk,
209 				   struct key *keyring)
210 {
211 	unsigned long flags;
212 	struct key *old;
213 	char buf[20];
214 	int ret;
215 
216 	/* create an empty session keyring */
217 	if (!keyring) {
218 		sprintf(buf, "_ses.%u", tsk->tgid);
219 
220 		keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
221 		if (IS_ERR(keyring)) {
222 			ret = PTR_ERR(keyring);
223 			goto error;
224 		}
225 	}
226 	else {
227 		atomic_inc(&keyring->usage);
228 	}
229 
230 	/* install the keyring */
231 	spin_lock_irqsave(&tsk->sighand->siglock, flags);
232 	old = tsk->signal->session_keyring;
233 	tsk->signal->session_keyring = keyring;
234 	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
235 
236 	ret = 0;
237 
238 	key_put(old);
239  error:
240 	return ret;
241 
242 } /* end install_session_keyring() */
243 
244 /*****************************************************************************/
245 /*
246  * copy the keys in a thread group for fork without CLONE_THREAD
247  */
248 int copy_thread_group_keys(struct task_struct *tsk)
249 {
250 	unsigned long flags;
251 
252 	key_check(current->thread_group->session_keyring);
253 	key_check(current->thread_group->process_keyring);
254 
255 	/* no process keyring yet */
256 	tsk->signal->process_keyring = NULL;
257 
258 	/* same session keyring */
259 	spin_lock_irqsave(&current->sighand->siglock, flags);
260 	tsk->signal->session_keyring =
261 		key_get(current->signal->session_keyring);
262 	spin_unlock_irqrestore(&current->sighand->siglock, flags);
263 
264 	return 0;
265 
266 } /* end copy_thread_group_keys() */
267 
268 /*****************************************************************************/
269 /*
270  * copy the keys for fork
271  */
272 int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
273 {
274 	key_check(tsk->thread_keyring);
275 
276 	/* no thread keyring yet */
277 	tsk->thread_keyring = NULL;
278 	return 0;
279 
280 } /* end copy_keys() */
281 
282 /*****************************************************************************/
283 /*
284  * dispose of thread group keys upon thread group destruction
285  */
286 void exit_thread_group_keys(struct signal_struct *tg)
287 {
288 	key_put(tg->session_keyring);
289 	key_put(tg->process_keyring);
290 
291 } /* end exit_thread_group_keys() */
292 
293 /*****************************************************************************/
294 /*
295  * dispose of keys upon thread exit
296  */
297 void exit_keys(struct task_struct *tsk)
298 {
299 	key_put(tsk->thread_keyring);
300 
301 } /* end exit_keys() */
302 
303 /*****************************************************************************/
304 /*
305  * deal with execve()
306  */
307 int exec_keys(struct task_struct *tsk)
308 {
309 	unsigned long flags;
310 	struct key *old;
311 
312 	/* newly exec'd tasks don't get a thread keyring */
313 	task_lock(tsk);
314 	old = tsk->thread_keyring;
315 	tsk->thread_keyring = NULL;
316 	task_unlock(tsk);
317 
318 	key_put(old);
319 
320 	/* discard the process keyring from a newly exec'd task */
321 	spin_lock_irqsave(&tsk->sighand->siglock, flags);
322 	old = tsk->signal->process_keyring;
323 	tsk->signal->process_keyring = NULL;
324 	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
325 
326 	key_put(old);
327 
328 	return 0;
329 
330 } /* end exec_keys() */
331 
332 /*****************************************************************************/
333 /*
334  * deal with SUID programs
335  * - we might want to make this invent a new session keyring
336  */
337 int suid_keys(struct task_struct *tsk)
338 {
339 	return 0;
340 
341 } /* end suid_keys() */
342 
343 /*****************************************************************************/
344 /*
345  * the filesystem user ID changed
346  */
347 void key_fsuid_changed(struct task_struct *tsk)
348 {
349 	/* update the ownership of the thread keyring */
350 	if (tsk->thread_keyring) {
351 		down_write(&tsk->thread_keyring->sem);
352 		write_lock(&tsk->thread_keyring->lock);
353 		tsk->thread_keyring->uid = tsk->fsuid;
354 		write_unlock(&tsk->thread_keyring->lock);
355 		up_write(&tsk->thread_keyring->sem);
356 	}
357 
358 } /* end key_fsuid_changed() */
359 
360 /*****************************************************************************/
361 /*
362  * the filesystem group ID changed
363  */
364 void key_fsgid_changed(struct task_struct *tsk)
365 {
366 	/* update the ownership of the thread keyring */
367 	if (tsk->thread_keyring) {
368 		down_write(&tsk->thread_keyring->sem);
369 		write_lock(&tsk->thread_keyring->lock);
370 		tsk->thread_keyring->gid = tsk->fsgid;
371 		write_unlock(&tsk->thread_keyring->lock);
372 		up_write(&tsk->thread_keyring->sem);
373 	}
374 
375 } /* end key_fsgid_changed() */
376 
377 /*****************************************************************************/
378 /*
379  * search the process keyrings for the first matching key
380  * - we use the supplied match function to see if the description (or other
381  *   feature of interest) matches
382  * - we return -EAGAIN if we didn't find any matching key
383  * - we return -ENOKEY if we found only negative matching keys
384  */
385 struct key *search_process_keyrings_aux(struct key_type *type,
386 					const void *description,
387 					key_match_func_t match)
388 {
389 	struct task_struct *tsk = current;
390 	unsigned long flags;
391 	struct key *key, *ret, *err, *tmp;
392 
393 	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 	 * searchable, but we failed to find a key or we found a negative key;
395 	 * otherwise we want to return a sample error (probably -EACCES) if
396 	 * none of the keyrings were searchable
397 	 *
398 	 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
399 	 */
400 	key = NULL;
401 	ret = NULL;
402 	err = ERR_PTR(-EAGAIN);
403 
404 	/* search the thread keyring first */
405 	if (tsk->thread_keyring) {
406 		key = keyring_search_aux(tsk->thread_keyring, type,
407 					 description, match);
408 		if (!IS_ERR(key))
409 			goto found;
410 
411 		switch (PTR_ERR(key)) {
412 		case -EAGAIN: /* no key */
413 			if (ret)
414 				break;
415 		case -ENOKEY: /* negative key */
416 			ret = key;
417 			break;
418 		default:
419 			err = key;
420 			break;
421 		}
422 	}
423 
424 	/* search the process keyring second */
425 	if (tsk->signal->process_keyring) {
426 		key = keyring_search_aux(tsk->signal->process_keyring,
427 					 type, description, match);
428 		if (!IS_ERR(key))
429 			goto found;
430 
431 		switch (PTR_ERR(key)) {
432 		case -EAGAIN: /* no key */
433 			if (ret)
434 				break;
435 		case -ENOKEY: /* negative key */
436 			ret = key;
437 			break;
438 		default:
439 			err = key;
440 			break;
441 		}
442 	}
443 
444 	/* search the session keyring last */
445 	spin_lock_irqsave(&tsk->sighand->siglock, flags);
446 
447 	tmp = tsk->signal->session_keyring;
448 	if (!tmp)
449 		tmp = tsk->user->session_keyring;
450 	atomic_inc(&tmp->usage);
451 
452 	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
453 
454 	key = keyring_search_aux(tmp, type, description, match);
455 	key_put(tmp);
456 	if (!IS_ERR(key))
457 		goto found;
458 
459 	switch (PTR_ERR(key)) {
460 	case -EAGAIN: /* no key */
461 		if (ret)
462 			break;
463 	case -ENOKEY: /* negative key */
464 		ret = key;
465 		break;
466 	default:
467 		err = key;
468 		break;
469 	}
470 
471 	/* no key - decide on the error we're going to go for */
472 	key = ret ? ret : err;
473 
474  found:
475 	return key;
476 
477 } /* end search_process_keyrings_aux() */
478 
479 /*****************************************************************************/
480 /*
481  * search the process keyrings for the first matching key
482  * - we return -EAGAIN if we didn't find any matching key
483  * - we return -ENOKEY if we found only negative matching keys
484  */
485 struct key *search_process_keyrings(struct key_type *type,
486 				    const char *description)
487 {
488 	return search_process_keyrings_aux(type, description, type->match);
489 
490 } /* end search_process_keyrings() */
491 
492 /*****************************************************************************/
493 /*
494  * lookup a key given a key ID from userspace with a given permissions mask
495  * - don't create special keyrings unless so requested
496  * - partially constructed keys aren't found unless requested
497  */
498 struct key *lookup_user_key(key_serial_t id, int create, int partial,
499 			    key_perm_t perm)
500 {
501 	struct task_struct *tsk = current;
502 	unsigned long flags;
503 	struct key *key;
504 	int ret;
505 
506 	key = ERR_PTR(-ENOKEY);
507 
508 	switch (id) {
509 	case KEY_SPEC_THREAD_KEYRING:
510 		if (!tsk->thread_keyring) {
511 			if (!create)
512 				goto error;
513 
514 			ret = install_thread_keyring(tsk);
515 			if (ret < 0) {
516 				key = ERR_PTR(ret);
517 				goto error;
518 			}
519 		}
520 
521 		key = tsk->thread_keyring;
522 		atomic_inc(&key->usage);
523 		break;
524 
525 	case KEY_SPEC_PROCESS_KEYRING:
526 		if (!tsk->signal->process_keyring) {
527 			if (!create)
528 				goto error;
529 
530 			ret = install_process_keyring(tsk);
531 			if (ret < 0) {
532 				key = ERR_PTR(ret);
533 				goto error;
534 			}
535 		}
536 
537 		key = tsk->signal->process_keyring;
538 		atomic_inc(&key->usage);
539 		break;
540 
541 	case KEY_SPEC_SESSION_KEYRING:
542 		if (!tsk->signal->session_keyring) {
543 			/* always install a session keyring upon access if one
544 			 * doesn't exist yet */
545 			ret = install_session_keyring(
546 			       tsk, tsk->user->session_keyring);
547 			if (ret < 0)
548 				goto error;
549 		}
550 
551 		spin_lock_irqsave(&tsk->sighand->siglock, flags);
552 		key = tsk->signal->session_keyring;
553 		atomic_inc(&key->usage);
554 		spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
555 		break;
556 
557 	case KEY_SPEC_USER_KEYRING:
558 		key = tsk->user->uid_keyring;
559 		atomic_inc(&key->usage);
560 		break;
561 
562 	case KEY_SPEC_USER_SESSION_KEYRING:
563 		key = tsk->user->session_keyring;
564 		atomic_inc(&key->usage);
565 		break;
566 
567 	case KEY_SPEC_GROUP_KEYRING:
568 		/* group keyrings are not yet supported */
569 		key = ERR_PTR(-EINVAL);
570 		goto error;
571 
572 	default:
573 		key = ERR_PTR(-EINVAL);
574 		if (id < 1)
575 			goto error;
576 
577 		key = key_lookup(id);
578 		if (IS_ERR(key))
579 			goto error;
580 		break;
581 	}
582 
583 	/* check the status and permissions */
584 	if (perm) {
585 		ret = key_validate(key);
586 		if (ret < 0)
587 			goto invalid_key;
588 	}
589 
590 	ret = -EIO;
591 	if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED))
592 		goto invalid_key;
593 
594 	ret = -EACCES;
595 	if (!key_permission(key, perm))
596 		goto invalid_key;
597 
598  error:
599 	return key;
600 
601  invalid_key:
602 	key_put(key);
603 	key = ERR_PTR(ret);
604 	goto error;
605 
606 } /* end lookup_user_key() */
607 
608 /*****************************************************************************/
609 /*
610  * join the named keyring as the session keyring if possible, or attempt to
611  * create a new one of that name if not
612  * - if the name is NULL, an empty anonymous keyring is installed instead
613  * - named session keyring joining is done with a semaphore held
614  */
615 long join_session_keyring(const char *name)
616 {
617 	struct task_struct *tsk = current;
618 	unsigned long flags;
619 	struct key *keyring;
620 	long ret;
621 
622 	/* if no name is provided, install an anonymous keyring */
623 	if (!name) {
624 		ret = install_session_keyring(tsk, NULL);
625 		if (ret < 0)
626 			goto error;
627 
628 		spin_lock_irqsave(&tsk->sighand->siglock, flags);
629 		ret = tsk->signal->session_keyring->serial;
630 		spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
631 		goto error;
632 	}
633 
634 	/* allow the user to join or create a named keyring */
635 	down(&key_session_sem);
636 
637 	/* look for an existing keyring of this name */
638 	keyring = find_keyring_by_name(name, 0);
639 	if (PTR_ERR(keyring) == -ENOKEY) {
640 		/* not found - try and create a new one */
641 		keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL);
642 		if (IS_ERR(keyring)) {
643 			ret = PTR_ERR(keyring);
644 			goto error;
645 		}
646 	}
647 	else if (IS_ERR(keyring)) {
648 		ret = PTR_ERR(keyring);
649 		goto error2;
650 	}
651 
652 	/* we've got a keyring - now to install it */
653 	ret = install_session_keyring(tsk, keyring);
654 	if (ret < 0)
655 		goto error2;
656 
657 	ret = keyring->serial;
658 	key_put(keyring);
659 
660  error2:
661 	up(&key_session_sem);
662  error:
663 	return ret;
664 
665 } /* end join_session_keyring() */
666