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