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