[PATCH] selinux: add hooks for key subsystem
[pandora-kernel.git] / security / keys / process_keys.c
1 /* process_keys.c: management of a process's keyrings
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
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 /* the root user's tracking struct */
27 struct key_user root_key_user = {
28         .usage          = ATOMIC_INIT(3),
29         .consq          = LIST_HEAD_INIT(root_key_user.consq),
30         .lock           = SPIN_LOCK_UNLOCKED,
31         .nkeys          = ATOMIC_INIT(2),
32         .nikeys         = ATOMIC_INIT(2),
33         .uid            = 0,
34 };
35
36 /* the root user's UID keyring */
37 struct key root_user_keyring = {
38         .usage          = ATOMIC_INIT(1),
39         .serial         = 2,
40         .type           = &key_type_keyring,
41         .user           = &root_key_user,
42         .sem            = __RWSEM_INITIALIZER(root_user_keyring.sem),
43         .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
44         .flags          = 1 << 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         .sem            = __RWSEM_INITIALIZER(root_session_keyring.sem),
58         .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
59         .flags          = 1 << KEY_FLAG_INSTANTIATED,
60         .description    = "_uid_ses.0",
61 #ifdef KEY_DEBUGGING
62         .magic          = KEY_DEBUG_MAGIC,
63 #endif
64 };
65
66 /*****************************************************************************/
67 /*
68  * allocate the keyrings to be associated with a UID
69  */
70 int alloc_uid_keyring(struct user_struct *user,
71                       struct task_struct *ctx)
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, ctx, 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, ctx, 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, tsk, 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 int install_process_keyring(struct task_struct *tsk)
171 {
172         struct key *keyring;
173         char buf[20];
174         int ret;
175
176         might_sleep();
177
178         if (!tsk->signal->process_keyring) {
179                 sprintf(buf, "_pid.%u", tsk->tgid);
180
181                 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
182                 if (IS_ERR(keyring)) {
183                         ret = PTR_ERR(keyring);
184                         goto error;
185                 }
186
187                 /* attach keyring */
188                 spin_lock_irq(&tsk->sighand->siglock);
189                 if (!tsk->signal->process_keyring) {
190                         tsk->signal->process_keyring = keyring;
191                         keyring = NULL;
192                 }
193                 spin_unlock_irq(&tsk->sighand->siglock);
194
195                 key_put(keyring);
196         }
197
198         ret = 0;
199 error:
200         return ret;
201
202 } /* end install_process_keyring() */
203
204 /*****************************************************************************/
205 /*
206  * install a session keyring, discarding the old one
207  * - if a keyring is not supplied, an empty one is invented
208  */
209 static int install_session_keyring(struct task_struct *tsk,
210                                    struct key *keyring)
211 {
212         struct key *old;
213         char buf[20];
214
215         might_sleep();
216
217         /* create an empty session keyring */
218         if (!keyring) {
219                 sprintf(buf, "_ses.%u", tsk->tgid);
220
221                 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
222                 if (IS_ERR(keyring))
223                         return PTR_ERR(keyring);
224         }
225         else {
226                 atomic_inc(&keyring->usage);
227         }
228
229         /* install the keyring */
230         spin_lock_irq(&tsk->sighand->siglock);
231         old = tsk->signal->session_keyring;
232         rcu_assign_pointer(tsk->signal->session_keyring, keyring);
233         spin_unlock_irq(&tsk->sighand->siglock);
234
235         /* we're using RCU on the pointer, but there's no point synchronising
236          * on it if it didn't previously point to anything */
237         if (old) {
238                 synchronize_rcu();
239                 key_put(old);
240         }
241
242         return 0;
243
244 } /* end install_session_keyring() */
245
246 /*****************************************************************************/
247 /*
248  * copy the keys in a thread group for fork without CLONE_THREAD
249  */
250 int copy_thread_group_keys(struct task_struct *tsk)
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         rcu_read_lock();
260         tsk->signal->session_keyring =
261                 key_get(rcu_dereference(current->signal->session_keyring));
262         rcu_read_unlock();
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         key_check(tsk->request_key_auth);
276
277         /* no thread keyring yet */
278         tsk->thread_keyring = NULL;
279
280         /* copy the request_key() authorisation for this thread */
281         key_get(tsk->request_key_auth);
282
283         return 0;
284
285 } /* end copy_keys() */
286
287 /*****************************************************************************/
288 /*
289  * dispose of thread group keys upon thread group destruction
290  */
291 void exit_thread_group_keys(struct signal_struct *tg)
292 {
293         key_put(tg->session_keyring);
294         key_put(tg->process_keyring);
295
296 } /* end exit_thread_group_keys() */
297
298 /*****************************************************************************/
299 /*
300  * dispose of per-thread keys upon thread exit
301  */
302 void exit_keys(struct task_struct *tsk)
303 {
304         key_put(tsk->thread_keyring);
305         key_put(tsk->request_key_auth);
306
307 } /* end exit_keys() */
308
309 /*****************************************************************************/
310 /*
311  * deal with execve()
312  */
313 int exec_keys(struct task_struct *tsk)
314 {
315         struct key *old;
316
317         /* newly exec'd tasks don't get a thread keyring */
318         task_lock(tsk);
319         old = tsk->thread_keyring;
320         tsk->thread_keyring = NULL;
321         task_unlock(tsk);
322
323         key_put(old);
324
325         /* discard the process keyring from a newly exec'd task */
326         spin_lock_irq(&tsk->sighand->siglock);
327         old = tsk->signal->process_keyring;
328         tsk->signal->process_keyring = NULL;
329         spin_unlock_irq(&tsk->sighand->siglock);
330
331         key_put(old);
332
333         return 0;
334
335 } /* end exec_keys() */
336
337 /*****************************************************************************/
338 /*
339  * deal with SUID programs
340  * - we might want to make this invent a new session keyring
341  */
342 int suid_keys(struct task_struct *tsk)
343 {
344         return 0;
345
346 } /* end suid_keys() */
347
348 /*****************************************************************************/
349 /*
350  * the filesystem user ID changed
351  */
352 void key_fsuid_changed(struct task_struct *tsk)
353 {
354         /* update the ownership of the thread keyring */
355         if (tsk->thread_keyring) {
356                 down_write(&tsk->thread_keyring->sem);
357                 tsk->thread_keyring->uid = tsk->fsuid;
358                 up_write(&tsk->thread_keyring->sem);
359         }
360
361 } /* end key_fsuid_changed() */
362
363 /*****************************************************************************/
364 /*
365  * the filesystem group ID changed
366  */
367 void key_fsgid_changed(struct task_struct *tsk)
368 {
369         /* update the ownership of the thread keyring */
370         if (tsk->thread_keyring) {
371                 down_write(&tsk->thread_keyring->sem);
372                 tsk->thread_keyring->gid = tsk->fsgid;
373                 up_write(&tsk->thread_keyring->sem);
374         }
375
376 } /* end key_fsgid_changed() */
377
378 /*****************************************************************************/
379 /*
380  * search the process keyrings for the first matching key
381  * - we use the supplied match function to see if the description (or other
382  *   feature of interest) matches
383  * - we return -EAGAIN if we didn't find any matching key
384  * - we return -ENOKEY if we found only negative matching keys
385  */
386 key_ref_t search_process_keyrings(struct key_type *type,
387                                   const void *description,
388                                   key_match_func_t match,
389                                   struct task_struct *context)
390 {
391         struct request_key_auth *rka;
392         key_ref_t key_ref, ret, err;
393
394         /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
395          * searchable, but we failed to find a key or we found a negative key;
396          * otherwise we want to return a sample error (probably -EACCES) if
397          * none of the keyrings were searchable
398          *
399          * in terms of priority: success > -ENOKEY > -EAGAIN > other error
400          */
401         key_ref = NULL;
402         ret = NULL;
403         err = ERR_PTR(-EAGAIN);
404
405         /* search the thread keyring first */
406         if (context->thread_keyring) {
407                 key_ref = keyring_search_aux(
408                         make_key_ref(context->thread_keyring, 1),
409                         context, 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         /* search the process keyring second */
427         if (context->signal->process_keyring) {
428                 key_ref = keyring_search_aux(
429                         make_key_ref(context->signal->process_keyring, 1),
430                         context, type, description, match);
431                 if (!IS_ERR(key_ref))
432                         goto found;
433
434                 switch (PTR_ERR(key_ref)) {
435                 case -EAGAIN: /* no key */
436                         if (ret)
437                                 break;
438                 case -ENOKEY: /* negative key */
439                         ret = key_ref;
440                         break;
441                 default:
442                         err = key_ref;
443                         break;
444                 }
445         }
446
447         /* search the session keyring */
448         if (context->signal->session_keyring) {
449                 rcu_read_lock();
450                 key_ref = keyring_search_aux(
451                         make_key_ref(rcu_dereference(
452                                              context->signal->session_keyring),
453                                      1),
454                         context, type, description, match);
455                 rcu_read_unlock();
456
457                 if (!IS_ERR(key_ref))
458                         goto found;
459
460                 switch (PTR_ERR(key_ref)) {
461                 case -EAGAIN: /* no key */
462                         if (ret)
463                                 break;
464                 case -ENOKEY: /* negative key */
465                         ret = key_ref;
466                         break;
467                 default:
468                         err = key_ref;
469                         break;
470                 }
471         }
472         /* or search the user-session keyring */
473         else {
474                 key_ref = keyring_search_aux(
475                         make_key_ref(context->user->session_keyring, 1),
476                         context, type, description, match);
477                 if (!IS_ERR(key_ref))
478                         goto found;
479
480                 switch (PTR_ERR(key_ref)) {
481                 case -EAGAIN: /* no key */
482                         if (ret)
483                                 break;
484                 case -ENOKEY: /* negative key */
485                         ret = key_ref;
486                         break;
487                 default:
488                         err = key_ref;
489                         break;
490                 }
491         }
492
493         /* if this process has an instantiation authorisation key, then we also
494          * search the keyrings of the process mentioned there
495          * - we don't permit access to request_key auth keys via this method
496          */
497         if (context->request_key_auth &&
498             context == current &&
499             type != &key_type_request_key_auth &&
500             key_validate(context->request_key_auth) == 0
501             ) {
502                 rka = context->request_key_auth->payload.data;
503
504                 key_ref = search_process_keyrings(type, description, match,
505                                                   rka->context);
506
507                 if (!IS_ERR(key_ref))
508                         goto found;
509
510                 switch (PTR_ERR(key_ref)) {
511                 case -EAGAIN: /* no key */
512                         if (ret)
513                                 break;
514                 case -ENOKEY: /* negative key */
515                         ret = key_ref;
516                         break;
517                 default:
518                         err = key_ref;
519                         break;
520                 }
521         }
522
523         /* no key - decide on the error we're going to go for */
524         key_ref = ret ? ret : err;
525
526 found:
527         return key_ref;
528
529 } /* end search_process_keyrings() */
530
531 /*****************************************************************************/
532 /*
533  * see if the key we're looking at is the target key
534  */
535 static int lookup_user_key_possessed(const struct key *key, const void *target)
536 {
537         return key == target;
538
539 } /* end lookup_user_key_possessed() */
540
541 /*****************************************************************************/
542 /*
543  * lookup a key given a key ID from userspace with a given permissions mask
544  * - don't create special keyrings unless so requested
545  * - partially constructed keys aren't found unless requested
546  */
547 key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
548                           int create, int partial, key_perm_t perm)
549 {
550         key_ref_t key_ref, skey_ref;
551         struct key *key;
552         int ret;
553
554         if (!context)
555                 context = current;
556
557         key_ref = ERR_PTR(-ENOKEY);
558
559         switch (id) {
560         case KEY_SPEC_THREAD_KEYRING:
561                 if (!context->thread_keyring) {
562                         if (!create)
563                                 goto error;
564
565                         ret = install_thread_keyring(context);
566                         if (ret < 0) {
567                                 key = ERR_PTR(ret);
568                                 goto error;
569                         }
570                 }
571
572                 key = context->thread_keyring;
573                 atomic_inc(&key->usage);
574                 key_ref = make_key_ref(key, 1);
575                 break;
576
577         case KEY_SPEC_PROCESS_KEYRING:
578                 if (!context->signal->process_keyring) {
579                         if (!create)
580                                 goto error;
581
582                         ret = install_process_keyring(context);
583                         if (ret < 0) {
584                                 key = ERR_PTR(ret);
585                                 goto error;
586                         }
587                 }
588
589                 key = context->signal->process_keyring;
590                 atomic_inc(&key->usage);
591                 key_ref = make_key_ref(key, 1);
592                 break;
593
594         case KEY_SPEC_SESSION_KEYRING:
595                 if (!context->signal->session_keyring) {
596                         /* always install a session keyring upon access if one
597                          * doesn't exist yet */
598                         ret = install_session_keyring(
599                                 context, context->user->session_keyring);
600                         if (ret < 0)
601                                 goto error;
602                 }
603
604                 rcu_read_lock();
605                 key = rcu_dereference(context->signal->session_keyring);
606                 atomic_inc(&key->usage);
607                 rcu_read_unlock();
608                 key_ref = make_key_ref(key, 1);
609                 break;
610
611         case KEY_SPEC_USER_KEYRING:
612                 key = context->user->uid_keyring;
613                 atomic_inc(&key->usage);
614                 key_ref = make_key_ref(key, 1);
615                 break;
616
617         case KEY_SPEC_USER_SESSION_KEYRING:
618                 key = context->user->session_keyring;
619                 atomic_inc(&key->usage);
620                 key_ref = make_key_ref(key, 1);
621                 break;
622
623         case KEY_SPEC_GROUP_KEYRING:
624                 /* group keyrings are not yet supported */
625                 key = ERR_PTR(-EINVAL);
626                 goto error;
627
628         case KEY_SPEC_REQKEY_AUTH_KEY:
629                 key = context->request_key_auth;
630                 if (!key)
631                         goto error;
632
633                 atomic_inc(&key->usage);
634                 key_ref = make_key_ref(key, 1);
635                 break;
636
637         default:
638                 key_ref = ERR_PTR(-EINVAL);
639                 if (id < 1)
640                         goto error;
641
642                 key = key_lookup(id);
643                 if (IS_ERR(key)) {
644                         key_ref = ERR_PTR(PTR_ERR(key));
645                         goto error;
646                 }
647
648                 key_ref = make_key_ref(key, 0);
649
650                 /* check to see if we possess the key */
651                 skey_ref = search_process_keyrings(key->type, key,
652                                                    lookup_user_key_possessed,
653                                                    current);
654
655                 if (!IS_ERR(skey_ref)) {
656                         key_put(key);
657                         key_ref = skey_ref;
658                 }
659
660                 break;
661         }
662
663         /* check the status */
664         if (perm) {
665                 ret = key_validate(key);
666                 if (ret < 0)
667                         goto invalid_key;
668         }
669
670         ret = -EIO;
671         if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
672                 goto invalid_key;
673
674         /* check the permissions */
675         ret = key_task_permission(key_ref, context, perm);
676         if (ret < 0)
677                 goto invalid_key;
678
679 error:
680         return key_ref;
681
682 invalid_key:
683         key_ref_put(key_ref);
684         key_ref = ERR_PTR(ret);
685         goto error;
686
687 } /* end lookup_user_key() */
688
689 /*****************************************************************************/
690 /*
691  * join the named keyring as the session keyring if possible, or attempt to
692  * create a new one of that name if not
693  * - if the name is NULL, an empty anonymous keyring is installed instead
694  * - named session keyring joining is done with a semaphore held
695  */
696 long join_session_keyring(const char *name)
697 {
698         struct task_struct *tsk = current;
699         struct key *keyring;
700         long ret;
701
702         /* if no name is provided, install an anonymous keyring */
703         if (!name) {
704                 ret = install_session_keyring(tsk, NULL);
705                 if (ret < 0)
706                         goto error;
707
708                 rcu_read_lock();
709                 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
710                 rcu_read_unlock();
711                 goto error;
712         }
713
714         /* allow the user to join or create a named keyring */
715         mutex_lock(&key_session_mutex);
716
717         /* look for an existing keyring of this name */
718         keyring = find_keyring_by_name(name, 0);
719         if (PTR_ERR(keyring) == -ENOKEY) {
720                 /* not found - try and create a new one */
721                 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
722                 if (IS_ERR(keyring)) {
723                         ret = PTR_ERR(keyring);
724                         goto error2;
725                 }
726         }
727         else if (IS_ERR(keyring)) {
728                 ret = PTR_ERR(keyring);
729                 goto error2;
730         }
731
732         /* we've got a keyring - now to install it */
733         ret = install_session_keyring(tsk, keyring);
734         if (ret < 0)
735                 goto error2;
736
737         ret = keyring->serial;
738         key_put(keyring);
739
740 error2:
741         mutex_unlock(&key_session_mutex);
742 error:
743         return ret;
744
745 } /* end join_session_keyring() */