Auto-update from upstream
[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         might_sleep();
395
396         /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
397          * searchable, but we failed to find a key or we found a negative key;
398          * otherwise we want to return a sample error (probably -EACCES) if
399          * none of the keyrings were searchable
400          *
401          * in terms of priority: success > -ENOKEY > -EAGAIN > other error
402          */
403         key_ref = NULL;
404         ret = NULL;
405         err = ERR_PTR(-EAGAIN);
406
407         /* search the thread keyring first */
408         if (context->thread_keyring) {
409                 key_ref = keyring_search_aux(
410                         make_key_ref(context->thread_keyring, 1),
411                         context, type, description, match);
412                 if (!IS_ERR(key_ref))
413                         goto found;
414
415                 switch (PTR_ERR(key_ref)) {
416                 case -EAGAIN: /* no key */
417                         if (ret)
418                                 break;
419                 case -ENOKEY: /* negative key */
420                         ret = key_ref;
421                         break;
422                 default:
423                         err = key_ref;
424                         break;
425                 }
426         }
427
428         /* search the process keyring second */
429         if (context->signal->process_keyring) {
430                 key_ref = keyring_search_aux(
431                         make_key_ref(context->signal->process_keyring, 1),
432                         context, type, description, match);
433                 if (!IS_ERR(key_ref))
434                         goto found;
435
436                 switch (PTR_ERR(key_ref)) {
437                 case -EAGAIN: /* no key */
438                         if (ret)
439                                 break;
440                 case -ENOKEY: /* negative key */
441                         ret = key_ref;
442                         break;
443                 default:
444                         err = key_ref;
445                         break;
446                 }
447         }
448
449         /* search the session keyring */
450         if (context->signal->session_keyring) {
451                 rcu_read_lock();
452                 key_ref = keyring_search_aux(
453                         make_key_ref(rcu_dereference(
454                                              context->signal->session_keyring),
455                                      1),
456                         context, type, description, match);
457                 rcu_read_unlock();
458
459                 if (!IS_ERR(key_ref))
460                         goto found;
461
462                 switch (PTR_ERR(key_ref)) {
463                 case -EAGAIN: /* no key */
464                         if (ret)
465                                 break;
466                 case -ENOKEY: /* negative key */
467                         ret = key_ref;
468                         break;
469                 default:
470                         err = key_ref;
471                         break;
472                 }
473         }
474         /* or search the user-session keyring */
475         else {
476                 key_ref = keyring_search_aux(
477                         make_key_ref(context->user->session_keyring, 1),
478                         context, type, description, match);
479                 if (!IS_ERR(key_ref))
480                         goto found;
481
482                 switch (PTR_ERR(key_ref)) {
483                 case -EAGAIN: /* no key */
484                         if (ret)
485                                 break;
486                 case -ENOKEY: /* negative key */
487                         ret = key_ref;
488                         break;
489                 default:
490                         err = key_ref;
491                         break;
492                 }
493         }
494
495         /* if this process has an instantiation authorisation key, then we also
496          * search the keyrings of the process mentioned there
497          * - we don't permit access to request_key auth keys via this method
498          */
499         if (context->request_key_auth &&
500             context == current &&
501             type != &key_type_request_key_auth
502             ) {
503                 /* defend against the auth key being revoked */
504                 down_read(&context->request_key_auth->sem);
505
506                 if (key_validate(context->request_key_auth) == 0) {
507                         rka = context->request_key_auth->payload.data;
508
509                         key_ref = search_process_keyrings(type, description,
510                                                           match, rka->context);
511
512                         up_read(&context->request_key_auth->sem);
513
514                         if (!IS_ERR(key_ref))
515                                 goto found;
516
517                         switch (PTR_ERR(key_ref)) {
518                         case -EAGAIN: /* no key */
519                                 if (ret)
520                                         break;
521                         case -ENOKEY: /* negative key */
522                                 ret = key_ref;
523                                 break;
524                         default:
525                                 err = key_ref;
526                                 break;
527                         }
528                 } else {
529                         up_read(&context->request_key_auth->sem);
530                 }
531         }
532
533         /* no key - decide on the error we're going to go for */
534         key_ref = ret ? ret : err;
535
536 found:
537         return key_ref;
538
539 } /* end search_process_keyrings() */
540
541 /*****************************************************************************/
542 /*
543  * see if the key we're looking at is the target key
544  */
545 static int lookup_user_key_possessed(const struct key *key, const void *target)
546 {
547         return key == target;
548
549 } /* end lookup_user_key_possessed() */
550
551 /*****************************************************************************/
552 /*
553  * lookup a key given a key ID from userspace with a given permissions mask
554  * - don't create special keyrings unless so requested
555  * - partially constructed keys aren't found unless requested
556  */
557 key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
558                           int create, int partial, key_perm_t perm)
559 {
560         key_ref_t key_ref, skey_ref;
561         struct key *key;
562         int ret;
563
564         if (!context)
565                 context = current;
566
567         key_ref = ERR_PTR(-ENOKEY);
568
569         switch (id) {
570         case KEY_SPEC_THREAD_KEYRING:
571                 if (!context->thread_keyring) {
572                         if (!create)
573                                 goto error;
574
575                         ret = install_thread_keyring(context);
576                         if (ret < 0) {
577                                 key = ERR_PTR(ret);
578                                 goto error;
579                         }
580                 }
581
582                 key = context->thread_keyring;
583                 atomic_inc(&key->usage);
584                 key_ref = make_key_ref(key, 1);
585                 break;
586
587         case KEY_SPEC_PROCESS_KEYRING:
588                 if (!context->signal->process_keyring) {
589                         if (!create)
590                                 goto error;
591
592                         ret = install_process_keyring(context);
593                         if (ret < 0) {
594                                 key = ERR_PTR(ret);
595                                 goto error;
596                         }
597                 }
598
599                 key = context->signal->process_keyring;
600                 atomic_inc(&key->usage);
601                 key_ref = make_key_ref(key, 1);
602                 break;
603
604         case KEY_SPEC_SESSION_KEYRING:
605                 if (!context->signal->session_keyring) {
606                         /* always install a session keyring upon access if one
607                          * doesn't exist yet */
608                         ret = install_session_keyring(
609                                 context, context->user->session_keyring);
610                         if (ret < 0)
611                                 goto error;
612                 }
613
614                 rcu_read_lock();
615                 key = rcu_dereference(context->signal->session_keyring);
616                 atomic_inc(&key->usage);
617                 rcu_read_unlock();
618                 key_ref = make_key_ref(key, 1);
619                 break;
620
621         case KEY_SPEC_USER_KEYRING:
622                 key = context->user->uid_keyring;
623                 atomic_inc(&key->usage);
624                 key_ref = make_key_ref(key, 1);
625                 break;
626
627         case KEY_SPEC_USER_SESSION_KEYRING:
628                 key = context->user->session_keyring;
629                 atomic_inc(&key->usage);
630                 key_ref = make_key_ref(key, 1);
631                 break;
632
633         case KEY_SPEC_GROUP_KEYRING:
634                 /* group keyrings are not yet supported */
635                 key = ERR_PTR(-EINVAL);
636                 goto error;
637
638         case KEY_SPEC_REQKEY_AUTH_KEY:
639                 key = context->request_key_auth;
640                 if (!key)
641                         goto error;
642
643                 atomic_inc(&key->usage);
644                 key_ref = make_key_ref(key, 1);
645                 break;
646
647         default:
648                 key_ref = ERR_PTR(-EINVAL);
649                 if (id < 1)
650                         goto error;
651
652                 key = key_lookup(id);
653                 if (IS_ERR(key)) {
654                         key_ref = ERR_PTR(PTR_ERR(key));
655                         goto error;
656                 }
657
658                 key_ref = make_key_ref(key, 0);
659
660                 /* check to see if we possess the key */
661                 skey_ref = search_process_keyrings(key->type, key,
662                                                    lookup_user_key_possessed,
663                                                    current);
664
665                 if (!IS_ERR(skey_ref)) {
666                         key_put(key);
667                         key_ref = skey_ref;
668                 }
669
670                 break;
671         }
672
673         /* check the status */
674         if (perm) {
675                 ret = key_validate(key);
676                 if (ret < 0)
677                         goto invalid_key;
678         }
679
680         ret = -EIO;
681         if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
682                 goto invalid_key;
683
684         /* check the permissions */
685         ret = key_task_permission(key_ref, context, perm);
686         if (ret < 0)
687                 goto invalid_key;
688
689 error:
690         return key_ref;
691
692 invalid_key:
693         key_ref_put(key_ref);
694         key_ref = ERR_PTR(ret);
695         goto error;
696
697 } /* end lookup_user_key() */
698
699 /*****************************************************************************/
700 /*
701  * join the named keyring as the session keyring if possible, or attempt to
702  * create a new one of that name if not
703  * - if the name is NULL, an empty anonymous keyring is installed instead
704  * - named session keyring joining is done with a semaphore held
705  */
706 long join_session_keyring(const char *name)
707 {
708         struct task_struct *tsk = current;
709         struct key *keyring;
710         long ret;
711
712         /* if no name is provided, install an anonymous keyring */
713         if (!name) {
714                 ret = install_session_keyring(tsk, NULL);
715                 if (ret < 0)
716                         goto error;
717
718                 rcu_read_lock();
719                 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
720                 rcu_read_unlock();
721                 goto error;
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, 0);
729         if (PTR_ERR(keyring) == -ENOKEY) {
730                 /* not found - try and create a new one */
731                 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
732                 if (IS_ERR(keyring)) {
733                         ret = PTR_ERR(keyring);
734                         goto error2;
735                 }
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(tsk, keyring);
744         if (ret < 0)
745                 goto error2;
746
747         ret = keyring->serial;
748         key_put(keyring);
749
750 error2:
751         mutex_unlock(&key_session_mutex);
752 error:
753         return ret;
754
755 } /* end join_session_keyring() */