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