Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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