]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - security/keys/process_keys.c
CRED: Use RCU to access another task's creds and to release a task's own creds
[linux-2.6-omap-h63xx.git] / 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->signal->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->sighand->siglock);
204                 if (!tsk->signal->process_keyring) {
205                         tsk->signal->process_keyring = keyring;
206                         keyring = NULL;
207                 }
208                 spin_unlock_irq(&tsk->sighand->siglock);
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->signal->session_keyring)
239                         flags = KEY_ALLOC_IN_QUOTA;
240
241                 keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
242                                         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->sighand->siglock);
252         old = tsk->signal->session_keyring;
253         rcu_assign_pointer(tsk->signal->session_keyring, keyring);
254         spin_unlock_irq(&tsk->sighand->siglock);
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 in a thread group for fork without CLONE_THREAD
270  */
271 int copy_thread_group_keys(struct task_struct *tsk)
272 {
273         key_check(current->thread_group->session_keyring);
274         key_check(current->thread_group->process_keyring);
275
276         /* no process keyring yet */
277         tsk->signal->process_keyring = NULL;
278
279         /* same session keyring */
280         rcu_read_lock();
281         tsk->signal->session_keyring =
282                 key_get(rcu_dereference(current->signal->session_keyring));
283         rcu_read_unlock();
284
285         return 0;
286
287 } /* end copy_thread_group_keys() */
288
289 /*****************************************************************************/
290 /*
291  * copy the keys for fork
292  */
293 int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
294 {
295         key_check(tsk->cred->thread_keyring);
296         key_check(tsk->cred->request_key_auth);
297
298         /* no thread keyring yet */
299         tsk->cred->thread_keyring = NULL;
300
301         /* copy the request_key() authorisation for this thread */
302         key_get(tsk->cred->request_key_auth);
303
304         return 0;
305
306 } /* end copy_keys() */
307
308 /*****************************************************************************/
309 /*
310  * dispose of thread group keys upon thread group destruction
311  */
312 void exit_thread_group_keys(struct signal_struct *tg)
313 {
314         key_put(tg->session_keyring);
315         key_put(tg->process_keyring);
316
317 } /* end exit_thread_group_keys() */
318
319 /*****************************************************************************/
320 /*
321  * dispose of per-thread keys upon thread exit
322  */
323 void exit_keys(struct task_struct *tsk)
324 {
325         key_put(tsk->cred->thread_keyring);
326         key_put(tsk->cred->request_key_auth);
327
328 } /* end exit_keys() */
329
330 /*****************************************************************************/
331 /*
332  * deal with execve()
333  */
334 int exec_keys(struct task_struct *tsk)
335 {
336         struct key *old;
337
338         /* newly exec'd tasks don't get a thread keyring */
339         task_lock(tsk);
340         old = tsk->cred->thread_keyring;
341         tsk->cred->thread_keyring = NULL;
342         task_unlock(tsk);
343
344         key_put(old);
345
346         /* discard the process keyring from a newly exec'd task */
347         spin_lock_irq(&tsk->sighand->siglock);
348         old = tsk->signal->process_keyring;
349         tsk->signal->process_keyring = NULL;
350         spin_unlock_irq(&tsk->sighand->siglock);
351
352         key_put(old);
353
354         return 0;
355
356 } /* end exec_keys() */
357
358 /*****************************************************************************/
359 /*
360  * deal with SUID programs
361  * - we might want to make this invent a new session keyring
362  */
363 int suid_keys(struct task_struct *tsk)
364 {
365         return 0;
366
367 } /* end suid_keys() */
368
369 /*****************************************************************************/
370 /*
371  * the filesystem user ID changed
372  */
373 void key_fsuid_changed(struct task_struct *tsk)
374 {
375         /* update the ownership of the thread keyring */
376         BUG_ON(!tsk->cred);
377         if (tsk->cred->thread_keyring) {
378                 down_write(&tsk->cred->thread_keyring->sem);
379                 tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
380                 up_write(&tsk->cred->thread_keyring->sem);
381         }
382
383 } /* end key_fsuid_changed() */
384
385 /*****************************************************************************/
386 /*
387  * the filesystem group ID changed
388  */
389 void key_fsgid_changed(struct task_struct *tsk)
390 {
391         /* update the ownership of the thread keyring */
392         BUG_ON(!tsk->cred);
393         if (tsk->cred->thread_keyring) {
394                 down_write(&tsk->cred->thread_keyring->sem);
395                 tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
396                 up_write(&tsk->cred->thread_keyring->sem);
397         }
398
399 } /* end key_fsgid_changed() */
400
401 /*****************************************************************************/
402 /*
403  * search the process keyrings for the first matching key
404  * - we use the supplied match function to see if the description (or other
405  *   feature of interest) matches
406  * - we return -EAGAIN if we didn't find any matching key
407  * - we return -ENOKEY if we found only negative matching keys
408  */
409 key_ref_t search_process_keyrings(struct key_type *type,
410                                   const void *description,
411                                   key_match_func_t match,
412                                   struct task_struct *context)
413 {
414         struct request_key_auth *rka;
415         struct cred *cred;
416         key_ref_t key_ref, ret, err;
417
418         might_sleep();
419
420         cred = get_task_cred(context);
421
422         /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
423          * searchable, but we failed to find a key or we found a negative key;
424          * otherwise we want to return a sample error (probably -EACCES) if
425          * none of the keyrings were searchable
426          *
427          * in terms of priority: success > -ENOKEY > -EAGAIN > other error
428          */
429         key_ref = NULL;
430         ret = NULL;
431         err = ERR_PTR(-EAGAIN);
432
433         /* search the thread keyring first */
434         if (cred->thread_keyring) {
435                 key_ref = keyring_search_aux(
436                         make_key_ref(cred->thread_keyring, 1),
437                         context, type, description, match);
438                 if (!IS_ERR(key_ref))
439                         goto found;
440
441                 switch (PTR_ERR(key_ref)) {
442                 case -EAGAIN: /* no key */
443                         if (ret)
444                                 break;
445                 case -ENOKEY: /* negative key */
446                         ret = key_ref;
447                         break;
448                 default:
449                         err = key_ref;
450                         break;
451                 }
452         }
453
454         /* search the process keyring second */
455         if (context->signal->process_keyring) {
456                 key_ref = keyring_search_aux(
457                         make_key_ref(context->signal->process_keyring, 1),
458                         context, type, description, match);
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
475         /* search the session keyring */
476         if (context->signal->session_keyring) {
477                 rcu_read_lock();
478                 key_ref = keyring_search_aux(
479                         make_key_ref(rcu_dereference(
480                                              context->signal->session_keyring),
481                                      1),
482                         context, type, description, match);
483                 rcu_read_unlock();
484
485                 if (!IS_ERR(key_ref))
486                         goto found;
487
488                 switch (PTR_ERR(key_ref)) {
489                 case -EAGAIN: /* no key */
490                         if (ret)
491                                 break;
492                 case -ENOKEY: /* negative key */
493                         ret = key_ref;
494                         break;
495                 default:
496                         err = key_ref;
497                         break;
498                 }
499         }
500         /* or search the user-session keyring */
501         else if (cred->user->session_keyring) {
502                 key_ref = keyring_search_aux(
503                         make_key_ref(cred->user->session_keyring, 1),
504                         context, type, description, match);
505                 if (!IS_ERR(key_ref))
506                         goto found;
507
508                 switch (PTR_ERR(key_ref)) {
509                 case -EAGAIN: /* no key */
510                         if (ret)
511                                 break;
512                 case -ENOKEY: /* negative key */
513                         ret = key_ref;
514                         break;
515                 default:
516                         err = key_ref;
517                         break;
518                 }
519         }
520
521         /* if this process has an instantiation authorisation key, then we also
522          * search the keyrings of the process mentioned there
523          * - we don't permit access to request_key auth keys via this method
524          */
525         if (cred->request_key_auth &&
526             context == current &&
527             type != &key_type_request_key_auth
528             ) {
529                 /* defend against the auth key being revoked */
530                 down_read(&cred->request_key_auth->sem);
531
532                 if (key_validate(cred->request_key_auth) == 0) {
533                         rka = cred->request_key_auth->payload.data;
534
535                         key_ref = search_process_keyrings(type, description,
536                                                           match, rka->context);
537
538                         up_read(&cred->request_key_auth->sem);
539
540                         if (!IS_ERR(key_ref))
541                                 goto found;
542
543                         switch (PTR_ERR(key_ref)) {
544                         case -EAGAIN: /* no key */
545                                 if (ret)
546                                         break;
547                         case -ENOKEY: /* negative key */
548                                 ret = key_ref;
549                                 break;
550                         default:
551                                 err = key_ref;
552                                 break;
553                         }
554                 } else {
555                         up_read(&cred->request_key_auth->sem);
556                 }
557         }
558
559         /* no key - decide on the error we're going to go for */
560         key_ref = ret ? ret : err;
561
562 found:
563         put_cred(cred);
564         return key_ref;
565
566 } /* end search_process_keyrings() */
567
568 /*****************************************************************************/
569 /*
570  * see if the key we're looking at is the target key
571  */
572 static int lookup_user_key_possessed(const struct key *key, const void *target)
573 {
574         return key == target;
575
576 } /* end lookup_user_key_possessed() */
577
578 /*****************************************************************************/
579 /*
580  * lookup a key given a key ID from userspace with a given permissions mask
581  * - don't create special keyrings unless so requested
582  * - partially constructed keys aren't found unless requested
583  */
584 key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
585                           key_perm_t perm)
586 {
587         struct request_key_auth *rka;
588         struct task_struct *t = current;
589         struct cred *cred = current_cred();
590         struct key *key;
591         key_ref_t key_ref, skey_ref;
592         int ret;
593
594         key_ref = ERR_PTR(-ENOKEY);
595
596         switch (id) {
597         case KEY_SPEC_THREAD_KEYRING:
598                 if (!cred->thread_keyring) {
599                         if (!create)
600                                 goto error;
601
602                         ret = install_thread_keyring();
603                         if (ret < 0) {
604                                 key = ERR_PTR(ret);
605                                 goto error;
606                         }
607                 }
608
609                 key = cred->thread_keyring;
610                 atomic_inc(&key->usage);
611                 key_ref = make_key_ref(key, 1);
612                 break;
613
614         case KEY_SPEC_PROCESS_KEYRING:
615                 if (!t->signal->process_keyring) {
616                         if (!create)
617                                 goto error;
618
619                         ret = install_process_keyring();
620                         if (ret < 0) {
621                                 key = ERR_PTR(ret);
622                                 goto error;
623                         }
624                 }
625
626                 key = t->signal->process_keyring;
627                 atomic_inc(&key->usage);
628                 key_ref = make_key_ref(key, 1);
629                 break;
630
631         case KEY_SPEC_SESSION_KEYRING:
632                 if (!t->signal->session_keyring) {
633                         /* always install a session keyring upon access if one
634                          * doesn't exist yet */
635                         ret = install_user_keyrings();
636                         if (ret < 0)
637                                 goto error;
638                         ret = install_session_keyring(
639                                 cred->user->session_keyring);
640                         if (ret < 0)
641                                 goto error;
642                 }
643
644                 rcu_read_lock();
645                 key = rcu_dereference(t->signal->session_keyring);
646                 atomic_inc(&key->usage);
647                 rcu_read_unlock();
648                 key_ref = make_key_ref(key, 1);
649                 break;
650
651         case KEY_SPEC_USER_KEYRING:
652                 if (!cred->user->uid_keyring) {
653                         ret = install_user_keyrings();
654                         if (ret < 0)
655                                 goto error;
656                 }
657
658                 key = cred->user->uid_keyring;
659                 atomic_inc(&key->usage);
660                 key_ref = make_key_ref(key, 1);
661                 break;
662
663         case KEY_SPEC_USER_SESSION_KEYRING:
664                 if (!cred->user->session_keyring) {
665                         ret = install_user_keyrings();
666                         if (ret < 0)
667                                 goto error;
668                 }
669
670                 key = cred->user->session_keyring;
671                 atomic_inc(&key->usage);
672                 key_ref = make_key_ref(key, 1);
673                 break;
674
675         case KEY_SPEC_GROUP_KEYRING:
676                 /* group keyrings are not yet supported */
677                 key = ERR_PTR(-EINVAL);
678                 goto error;
679
680         case KEY_SPEC_REQKEY_AUTH_KEY:
681                 key = cred->request_key_auth;
682                 if (!key)
683                         goto error;
684
685                 atomic_inc(&key->usage);
686                 key_ref = make_key_ref(key, 1);
687                 break;
688
689         case KEY_SPEC_REQUESTOR_KEYRING:
690                 if (!cred->request_key_auth)
691                         goto error;
692
693                 down_read(&cred->request_key_auth->sem);
694                 if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) {
695                         key_ref = ERR_PTR(-EKEYREVOKED);
696                         key = NULL;
697                 } else {
698                         rka = cred->request_key_auth->payload.data;
699                         key = rka->dest_keyring;
700                         atomic_inc(&key->usage);
701                 }
702                 up_read(&cred->request_key_auth->sem);
703                 if (!key)
704                         goto error;
705                 key_ref = make_key_ref(key, 1);
706                 break;
707
708         default:
709                 key_ref = ERR_PTR(-EINVAL);
710                 if (id < 1)
711                         goto error;
712
713                 key = key_lookup(id);
714                 if (IS_ERR(key)) {
715                         key_ref = ERR_CAST(key);
716                         goto error;
717                 }
718
719                 key_ref = make_key_ref(key, 0);
720
721                 /* check to see if we possess the key */
722                 skey_ref = search_process_keyrings(key->type, key,
723                                                    lookup_user_key_possessed,
724                                                    current);
725
726                 if (!IS_ERR(skey_ref)) {
727                         key_put(key);
728                         key_ref = skey_ref;
729                 }
730
731                 break;
732         }
733
734         if (!partial) {
735                 ret = wait_for_key_construction(key, true);
736                 switch (ret) {
737                 case -ERESTARTSYS:
738                         goto invalid_key;
739                 default:
740                         if (perm)
741                                 goto invalid_key;
742                 case 0:
743                         break;
744                 }
745         } else if (perm) {
746                 ret = key_validate(key);
747                 if (ret < 0)
748                         goto invalid_key;
749         }
750
751         ret = -EIO;
752         if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
753                 goto invalid_key;
754
755         /* check the permissions */
756         ret = key_task_permission(key_ref, t, perm);
757         if (ret < 0)
758                 goto invalid_key;
759
760 error:
761         return key_ref;
762
763 invalid_key:
764         key_ref_put(key_ref);
765         key_ref = ERR_PTR(ret);
766         goto error;
767
768 } /* end lookup_user_key() */
769
770 /*****************************************************************************/
771 /*
772  * join the named keyring as the session keyring if possible, or attempt to
773  * create a new one of that name if not
774  * - if the name is NULL, an empty anonymous keyring is installed instead
775  * - named session keyring joining is done with a semaphore held
776  */
777 long join_session_keyring(const char *name)
778 {
779         struct task_struct *tsk = current;
780         struct key *keyring;
781         long ret;
782
783         /* if no name is provided, install an anonymous keyring */
784         if (!name) {
785                 ret = install_session_keyring(NULL);
786                 if (ret < 0)
787                         goto error;
788
789                 rcu_read_lock();
790                 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
791                 rcu_read_unlock();
792                 goto error;
793         }
794
795         /* allow the user to join or create a named keyring */
796         mutex_lock(&key_session_mutex);
797
798         /* look for an existing keyring of this name */
799         keyring = find_keyring_by_name(name, false);
800         if (PTR_ERR(keyring) == -ENOKEY) {
801                 /* not found - try and create a new one */
802                 keyring = keyring_alloc(name, tsk->cred->uid, tsk->cred->gid, tsk,
803                                         KEY_ALLOC_IN_QUOTA, NULL);
804                 if (IS_ERR(keyring)) {
805                         ret = PTR_ERR(keyring);
806                         goto error2;
807                 }
808         }
809         else if (IS_ERR(keyring)) {
810                 ret = PTR_ERR(keyring);
811                 goto error2;
812         }
813
814         /* we've got a keyring - now to install it */
815         ret = install_session_keyring(keyring);
816         if (ret < 0)
817                 goto error2;
818
819         ret = keyring->serial;
820         key_put(keyring);
821
822 error2:
823         mutex_unlock(&key_session_mutex);
824 error:
825         return ret;
826
827 } /* end join_session_keyring() */