linux/security/keys/process_keys.c
<<
>>
Prefs
   1/* Manage 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/keyctl.h>
  16#include <linux/fs.h>
  17#include <linux/err.h>
  18#include <linux/mutex.h>
  19#include <linux/security.h>
  20#include <linux/user_namespace.h>
  21#include <asm/uaccess.h>
  22#include "internal.h"
  23
  24/* Session keyring create vs join semaphore */
  25static DEFINE_MUTEX(key_session_mutex);
  26
  27/* User keyring creation semaphore */
  28static DEFINE_MUTEX(key_user_keyring_mutex);
  29
  30/* The root user's tracking struct */
  31struct key_user root_key_user = {
  32        .usage          = ATOMIC_INIT(3),
  33        .cons_lock      = __MUTEX_INITIALIZER(root_key_user.cons_lock),
  34        .lock           = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
  35        .nkeys          = ATOMIC_INIT(2),
  36        .nikeys         = ATOMIC_INIT(2),
  37        .uid            = GLOBAL_ROOT_UID,
  38};
  39
  40/*
  41 * Install the user and user session keyrings for the current process's UID.
  42 */
  43int 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        uid_t uid;
  51
  52        cred = current_cred();
  53        user = cred->user;
  54        uid = from_kuid(cred->user_ns, user->uid);
  55
  56        kenter("%p{%u}", user, uid);
  57
  58        if (user->uid_keyring) {
  59                kleave(" = 0 [exist]");
  60                return 0;
  61        }
  62
  63        mutex_lock(&key_user_keyring_mutex);
  64        ret = 0;
  65
  66        if (!user->uid_keyring) {
  67                /* get the UID-specific keyring
  68                 * - there may be one in existence already as it may have been
  69                 *   pinned by a session, but the user_struct pointing to it
  70                 *   may have been destroyed by setuid */
  71                sprintf(buf, "_uid.%u", uid);
  72
  73                uid_keyring = find_keyring_by_name(buf, true);
  74                if (IS_ERR(uid_keyring)) {
  75                        uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
  76                                                    cred, KEY_ALLOC_IN_QUOTA,
  77                                                    NULL);
  78                        if (IS_ERR(uid_keyring)) {
  79                                ret = PTR_ERR(uid_keyring);
  80                                goto error;
  81                        }
  82                }
  83
  84                /* get a default session keyring (which might also exist
  85                 * already) */
  86                sprintf(buf, "_uid_ses.%u", uid);
  87
  88                session_keyring = find_keyring_by_name(buf, true);
  89                if (IS_ERR(session_keyring)) {
  90                        session_keyring =
  91                                keyring_alloc(buf, user->uid, INVALID_GID,
  92                                              cred, KEY_ALLOC_IN_QUOTA, NULL);
  93                        if (IS_ERR(session_keyring)) {
  94                                ret = PTR_ERR(session_keyring);
  95                                goto error_release;
  96                        }
  97
  98                        /* we install a link from the user session keyring to
  99                         * the user keyring */
 100                        ret = key_link(session_keyring, uid_keyring);
 101                        if (ret < 0)
 102                                goto error_release_both;
 103                }
 104
 105                /* install the keyrings */
 106                user->uid_keyring = uid_keyring;
 107                user->session_keyring = session_keyring;
 108        }
 109
 110        mutex_unlock(&key_user_keyring_mutex);
 111        kleave(" = 0");
 112        return 0;
 113
 114error_release_both:
 115        key_put(session_keyring);
 116error_release:
 117        key_put(uid_keyring);
 118error:
 119        mutex_unlock(&key_user_keyring_mutex);
 120        kleave(" = %d", ret);
 121        return ret;
 122}
 123
 124/*
 125 * Install a fresh thread keyring directly to new credentials.  This keyring is
 126 * allowed to overrun the quota.
 127 */
 128int install_thread_keyring_to_cred(struct cred *new)
 129{
 130        struct key *keyring;
 131
 132        keyring = keyring_alloc("_tid", new->uid, new->gid, new,
 133                                KEY_ALLOC_QUOTA_OVERRUN, NULL);
 134        if (IS_ERR(keyring))
 135                return PTR_ERR(keyring);
 136
 137        new->thread_keyring = keyring;
 138        return 0;
 139}
 140
 141/*
 142 * Install a fresh thread keyring, discarding the old one.
 143 */
 144static int install_thread_keyring(void)
 145{
 146        struct cred *new;
 147        int ret;
 148
 149        new = prepare_creds();
 150        if (!new)
 151                return -ENOMEM;
 152
 153        BUG_ON(new->thread_keyring);
 154
 155        ret = install_thread_keyring_to_cred(new);
 156        if (ret < 0) {
 157                abort_creds(new);
 158                return ret;
 159        }
 160
 161        return commit_creds(new);
 162}
 163
 164/*
 165 * Install a process keyring directly to a credentials struct.
 166 *
 167 * Returns -EEXIST if there was already a process keyring, 0 if one installed,
 168 * and other value on any other error
 169 */
 170int install_process_keyring_to_cred(struct cred *new)
 171{
 172        struct key *keyring;
 173        int ret;
 174
 175        if (new->tgcred->process_keyring)
 176                return -EEXIST;
 177
 178        keyring = keyring_alloc("_pid", new->uid, new->gid,
 179                                new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
 180        if (IS_ERR(keyring))
 181                return PTR_ERR(keyring);
 182
 183        spin_lock_irq(&new->tgcred->lock);
 184        if (!new->tgcred->process_keyring) {
 185                new->tgcred->process_keyring = keyring;
 186                keyring = NULL;
 187                ret = 0;
 188        } else {
 189                ret = -EEXIST;
 190        }
 191        spin_unlock_irq(&new->tgcred->lock);
 192        key_put(keyring);
 193        return ret;
 194}
 195
 196/*
 197 * Make sure a process keyring is installed for the current process.  The
 198 * existing process keyring is not replaced.
 199 *
 200 * Returns 0 if there is a process keyring by the end of this function, some
 201 * error otherwise.
 202 */
 203static int install_process_keyring(void)
 204{
 205        struct cred *new;
 206        int ret;
 207
 208        new = prepare_creds();
 209        if (!new)
 210                return -ENOMEM;
 211
 212        ret = install_process_keyring_to_cred(new);
 213        if (ret < 0) {
 214                abort_creds(new);
 215                return ret != -EEXIST ? ret : 0;
 216        }
 217
 218        return commit_creds(new);
 219}
 220
 221/*
 222 * Install a session keyring directly to a credentials struct.
 223 */
 224int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
 225{
 226        unsigned long flags;
 227        struct key *old;
 228
 229        might_sleep();
 230
 231        /* create an empty session keyring */
 232        if (!keyring) {
 233                flags = KEY_ALLOC_QUOTA_OVERRUN;
 234                if (cred->tgcred->session_keyring)
 235                        flags = KEY_ALLOC_IN_QUOTA;
 236
 237                keyring = keyring_alloc("_ses", cred->uid, cred->gid,
 238                                        cred, flags, NULL);
 239                if (IS_ERR(keyring))
 240                        return PTR_ERR(keyring);
 241        } else {
 242                atomic_inc(&keyring->usage);
 243        }
 244
 245        /* install the keyring */
 246        spin_lock_irq(&cred->tgcred->lock);
 247        old = cred->tgcred->session_keyring;
 248        rcu_assign_pointer(cred->tgcred->session_keyring, keyring);
 249        spin_unlock_irq(&cred->tgcred->lock);
 250
 251        /* we're using RCU on the pointer, but there's no point synchronising
 252         * on it if it didn't previously point to anything */
 253        if (old) {
 254                synchronize_rcu();
 255                key_put(old);
 256        }
 257
 258        return 0;
 259}
 260
 261/*
 262 * Install a session keyring, discarding the old one.  If a keyring is not
 263 * supplied, an empty one is invented.
 264 */
 265static int install_session_keyring(struct key *keyring)
 266{
 267        struct cred *new;
 268        int ret;
 269
 270        new = prepare_creds();
 271        if (!new)
 272                return -ENOMEM;
 273
 274        ret = install_session_keyring_to_cred(new, keyring);
 275        if (ret < 0) {
 276                abort_creds(new);
 277                return ret;
 278        }
 279
 280        return commit_creds(new);
 281}
 282
 283/*
 284 * Handle the fsuid changing.
 285 */
 286void key_fsuid_changed(struct task_struct *tsk)
 287{
 288        /* update the ownership of the thread keyring */
 289        BUG_ON(!tsk->cred);
 290        if (tsk->cred->thread_keyring) {
 291                down_write(&tsk->cred->thread_keyring->sem);
 292                tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
 293                up_write(&tsk->cred->thread_keyring->sem);
 294        }
 295}
 296
 297/*
 298 * Handle the fsgid changing.
 299 */
 300void key_fsgid_changed(struct task_struct *tsk)
 301{
 302        /* update the ownership of the thread keyring */
 303        BUG_ON(!tsk->cred);
 304        if (tsk->cred->thread_keyring) {
 305                down_write(&tsk->cred->thread_keyring->sem);
 306                tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
 307                up_write(&tsk->cred->thread_keyring->sem);
 308        }
 309}
 310
 311/*
 312 * Search the process keyrings attached to the supplied cred for the first
 313 * matching key.
 314 *
 315 * The search criteria are the type and the match function.  The description is
 316 * given to the match function as a parameter, but doesn't otherwise influence
 317 * the search.  Typically the match function will compare the description
 318 * parameter to the key's description.
 319 *
 320 * This can only search keyrings that grant Search permission to the supplied
 321 * credentials.  Keyrings linked to searched keyrings will also be searched if
 322 * they grant Search permission too.  Keys can only be found if they grant
 323 * Search permission to the credentials.
 324 *
 325 * Returns a pointer to the key with the key usage count incremented if
 326 * successful, -EAGAIN if we didn't find any matching key or -ENOKEY if we only
 327 * matched negative keys.
 328 *
 329 * In the case of a successful return, the possession attribute is set on the
 330 * returned key reference.
 331 */
 332key_ref_t search_my_process_keyrings(struct key_type *type,
 333                                     const void *description,
 334                                     key_match_func_t match,
 335                                     bool no_state_check,
 336                                     const struct cred *cred)
 337{
 338        key_ref_t key_ref, ret, err;
 339
 340        /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
 341         * searchable, but we failed to find a key or we found a negative key;
 342         * otherwise we want to return a sample error (probably -EACCES) if
 343         * none of the keyrings were searchable
 344         *
 345         * in terms of priority: success > -ENOKEY > -EAGAIN > other error
 346         */
 347        key_ref = NULL;
 348        ret = NULL;
 349        err = ERR_PTR(-EAGAIN);
 350
 351        /* search the thread keyring first */
 352        if (cred->thread_keyring) {
 353                key_ref = keyring_search_aux(
 354                        make_key_ref(cred->thread_keyring, 1),
 355                        cred, type, description, match, no_state_check);
 356                if (!IS_ERR(key_ref))
 357                        goto found;
 358
 359                switch (PTR_ERR(key_ref)) {
 360                case -EAGAIN: /* no key */
 361                        if (ret)
 362                                break;
 363                case -ENOKEY: /* negative key */
 364                        ret = key_ref;
 365                        break;
 366                default:
 367                        err = key_ref;
 368                        break;
 369                }
 370        }
 371
 372        /* search the process keyring second */
 373        if (cred->tgcred->process_keyring) {
 374                key_ref = keyring_search_aux(
 375                        make_key_ref(cred->tgcred->process_keyring, 1),
 376                        cred, type, description, match, no_state_check);
 377                if (!IS_ERR(key_ref))
 378                        goto found;
 379
 380                switch (PTR_ERR(key_ref)) {
 381                case -EAGAIN: /* no key */
 382                        if (ret)
 383                                break;
 384                case -ENOKEY: /* negative key */
 385                        ret = key_ref;
 386                        break;
 387                default:
 388                        err = key_ref;
 389                        break;
 390                }
 391        }
 392
 393        /* search the session keyring */
 394        if (cred->tgcred->session_keyring) {
 395                rcu_read_lock();
 396                key_ref = keyring_search_aux(
 397                        make_key_ref(rcu_dereference(
 398                                             cred->tgcred->session_keyring),
 399                                     1),
 400                        cred, type, description, match, no_state_check);
 401                rcu_read_unlock();
 402
 403                if (!IS_ERR(key_ref))
 404                        goto found;
 405
 406                switch (PTR_ERR(key_ref)) {
 407                case -EAGAIN: /* no key */
 408                        if (ret)
 409                                break;
 410                case -ENOKEY: /* negative key */
 411                        ret = key_ref;
 412                        break;
 413                default:
 414                        err = key_ref;
 415                        break;
 416                }
 417        }
 418        /* or search the user-session keyring */
 419        else if (cred->user->session_keyring) {
 420                key_ref = keyring_search_aux(
 421                        make_key_ref(cred->user->session_keyring, 1),
 422                        cred, type, description, match, no_state_check);
 423                if (!IS_ERR(key_ref))
 424                        goto found;
 425
 426                switch (PTR_ERR(key_ref)) {
 427                case -EAGAIN: /* no key */
 428                        if (ret)
 429                                break;
 430                case -ENOKEY: /* negative key */
 431                        ret = key_ref;
 432                        break;
 433                default:
 434                        err = key_ref;
 435                        break;
 436                }
 437        }
 438
 439        /* no key - decide on the error we're going to go for */
 440        key_ref = ret ? ret : err;
 441
 442found:
 443        return key_ref;
 444}
 445
 446/*
 447 * Search the process keyrings attached to the supplied cred for the first
 448 * matching key in the manner of search_my_process_keyrings(), but also search
 449 * the keys attached to the assumed authorisation key using its credentials if
 450 * one is available.
 451 *
 452 * Return same as search_my_process_keyrings().
 453 */
 454key_ref_t search_process_keyrings(struct key_type *type,
 455                                  const void *description,
 456                                  key_match_func_t match,
 457                                  const struct cred *cred)
 458{
 459        struct request_key_auth *rka;
 460        key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
 461
 462        might_sleep();
 463
 464        key_ref = search_my_process_keyrings(type, description, match,
 465                                             false, cred);
 466        if (!IS_ERR(key_ref))
 467                goto found;
 468        err = key_ref;
 469
 470        /* if this process has an instantiation authorisation key, then we also
 471         * search the keyrings of the process mentioned there
 472         * - we don't permit access to request_key auth keys via this method
 473         */
 474        if (cred->request_key_auth &&
 475            cred == current_cred() &&
 476            type != &key_type_request_key_auth
 477            ) {
 478                /* defend against the auth key being revoked */
 479                down_read(&cred->request_key_auth->sem);
 480
 481                if (key_validate(cred->request_key_auth) == 0) {
 482                        rka = cred->request_key_auth->payload.data;
 483
 484                        key_ref = search_process_keyrings(type, description,
 485                                                          match, rka->cred);
 486
 487                        up_read(&cred->request_key_auth->sem);
 488
 489                        if (!IS_ERR(key_ref))
 490                                goto found;
 491
 492                        ret = key_ref;
 493                } else {
 494                        up_read(&cred->request_key_auth->sem);
 495                }
 496        }
 497
 498        /* no key - decide on the error we're going to go for */
 499        if (err == ERR_PTR(-ENOKEY) || ret == ERR_PTR(-ENOKEY))
 500                key_ref = ERR_PTR(-ENOKEY);
 501        else if (err == ERR_PTR(-EACCES))
 502                key_ref = ret;
 503        else
 504                key_ref = err;
 505
 506found:
 507        return key_ref;
 508}
 509
 510/*
 511 * See if the key we're looking at is the target key.
 512 */
 513int lookup_user_key_possessed(const struct key *key, const void *target)
 514{
 515        return key == target;
 516}
 517
 518/*
 519 * Look up a key ID given us by userspace with a given permissions mask to get
 520 * the key it refers to.
 521 *
 522 * Flags can be passed to request that special keyrings be created if referred
 523 * to directly, to permit partially constructed keys to be found and to skip
 524 * validity and permission checks on the found key.
 525 *
 526 * Returns a pointer to the key with an incremented usage count if successful;
 527 * -EINVAL if the key ID is invalid; -ENOKEY if the key ID does not correspond
 528 * to a key or the best found key was a negative key; -EKEYREVOKED or
 529 * -EKEYEXPIRED if the best found key was revoked or expired; -EACCES if the
 530 * found key doesn't grant the requested permit or the LSM denied access to it;
 531 * or -ENOMEM if a special keyring couldn't be created.
 532 *
 533 * In the case of a successful return, the possession attribute is set on the
 534 * returned key reference.
 535 */
 536key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 537                          key_perm_t perm)
 538{
 539        struct request_key_auth *rka;
 540        const struct cred *cred;
 541        struct key *key;
 542        key_ref_t key_ref, skey_ref;
 543        int ret;
 544
 545try_again:
 546        cred = get_current_cred();
 547        key_ref = ERR_PTR(-ENOKEY);
 548
 549        switch (id) {
 550        case KEY_SPEC_THREAD_KEYRING:
 551                if (!cred->thread_keyring) {
 552                        if (!(lflags & KEY_LOOKUP_CREATE))
 553                                goto error;
 554
 555                        ret = install_thread_keyring();
 556                        if (ret < 0) {
 557                                key_ref = ERR_PTR(ret);
 558                                goto error;
 559                        }
 560                        goto reget_creds;
 561                }
 562
 563                key = cred->thread_keyring;
 564                atomic_inc(&key->usage);
 565                key_ref = make_key_ref(key, 1);
 566                break;
 567
 568        case KEY_SPEC_PROCESS_KEYRING:
 569                if (!cred->tgcred->process_keyring) {
 570                        if (!(lflags & KEY_LOOKUP_CREATE))
 571                                goto error;
 572
 573                        ret = install_process_keyring();
 574                        if (ret < 0) {
 575                                key_ref = ERR_PTR(ret);
 576                                goto error;
 577                        }
 578                        goto reget_creds;
 579                }
 580
 581                key = cred->tgcred->process_keyring;
 582                atomic_inc(&key->usage);
 583                key_ref = make_key_ref(key, 1);
 584                break;
 585
 586        case KEY_SPEC_SESSION_KEYRING:
 587                if (!cred->tgcred->session_keyring) {
 588                        /* always install a session keyring upon access if one
 589                         * doesn't exist yet */
 590                        ret = install_user_keyrings();
 591                        if (ret < 0)
 592                                goto error;
 593                        if (lflags & KEY_LOOKUP_CREATE)
 594                                ret = join_session_keyring(NULL);
 595                        else
 596                                ret = install_session_keyring(
 597                                        cred->user->session_keyring);
 598
 599                        if (ret < 0)
 600                                goto error;
 601                        goto reget_creds;
 602                } else if (cred->tgcred->session_keyring ==
 603                           cred->user->session_keyring &&
 604                           lflags & KEY_LOOKUP_CREATE) {
 605                        ret = join_session_keyring(NULL);
 606                        if (ret < 0)
 607                                goto error;
 608                        goto reget_creds;
 609                }
 610
 611                rcu_read_lock();
 612                key = rcu_dereference(cred->tgcred->session_keyring);
 613                atomic_inc(&key->usage);
 614                rcu_read_unlock();
 615                key_ref = make_key_ref(key, 1);
 616                break;
 617
 618        case KEY_SPEC_USER_KEYRING:
 619                if (!cred->user->uid_keyring) {
 620                        ret = install_user_keyrings();
 621                        if (ret < 0)
 622                                goto error;
 623                }
 624
 625                key = cred->user->uid_keyring;
 626                atomic_inc(&key->usage);
 627                key_ref = make_key_ref(key, 1);
 628                break;
 629
 630        case KEY_SPEC_USER_SESSION_KEYRING:
 631                if (!cred->user->session_keyring) {
 632                        ret = install_user_keyrings();
 633                        if (ret < 0)
 634                                goto error;
 635                }
 636
 637                key = cred->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_ref = ERR_PTR(-EINVAL);
 645                goto error;
 646
 647        case KEY_SPEC_REQKEY_AUTH_KEY:
 648                key = cred->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        case KEY_SPEC_REQUESTOR_KEYRING:
 657                if (!cred->request_key_auth)
 658                        goto error;
 659
 660                down_read(&cred->request_key_auth->sem);
 661                if (test_bit(KEY_FLAG_REVOKED,
 662                             &cred->request_key_auth->flags)) {
 663                        key_ref = ERR_PTR(-EKEYREVOKED);
 664                        key = NULL;
 665                } else {
 666                        rka = cred->request_key_auth->payload.data;
 667                        key = rka->dest_keyring;
 668                        atomic_inc(&key->usage);
 669                }
 670                up_read(&cred->request_key_auth->sem);
 671                if (!key)
 672                        goto error;
 673                key_ref = make_key_ref(key, 1);
 674                break;
 675
 676        default:
 677                key_ref = ERR_PTR(-EINVAL);
 678                if (id < 1)
 679                        goto error;
 680
 681                key = key_lookup(id);
 682                if (IS_ERR(key)) {
 683                        key_ref = ERR_CAST(key);
 684                        goto error;
 685                }
 686
 687                key_ref = make_key_ref(key, 0);
 688
 689                /* check to see if we possess the key */
 690                skey_ref = search_process_keyrings(key->type, key,
 691                                                   lookup_user_key_possessed,
 692                                                   cred);
 693
 694                if (!IS_ERR(skey_ref)) {
 695                        key_put(key);
 696                        key_ref = skey_ref;
 697                }
 698
 699                break;
 700        }
 701
 702        /* unlink does not use the nominated key in any way, so can skip all
 703         * the permission checks as it is only concerned with the keyring */
 704        if (lflags & KEY_LOOKUP_FOR_UNLINK) {
 705                ret = 0;
 706                goto error;
 707        }
 708
 709        if (!(lflags & KEY_LOOKUP_PARTIAL)) {
 710                ret = wait_for_key_construction(key, true);
 711                switch (ret) {
 712                case -ERESTARTSYS:
 713                        goto invalid_key;
 714                default:
 715                        if (perm)
 716                                goto invalid_key;
 717                case 0:
 718                        break;
 719                }
 720        } else if (perm) {
 721                ret = key_validate(key);
 722                if (ret < 0)
 723                        goto invalid_key;
 724        }
 725
 726        ret = -EIO;
 727        if (!(lflags & KEY_LOOKUP_PARTIAL) &&
 728            !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 729                goto invalid_key;
 730
 731        /* check the permissions */
 732        ret = key_task_permission(key_ref, cred, perm);
 733        if (ret < 0)
 734                goto invalid_key;
 735
 736        key->last_used_at = current_kernel_time().tv_sec;
 737
 738error:
 739        put_cred(cred);
 740        return key_ref;
 741
 742invalid_key:
 743        key_ref_put(key_ref);
 744        key_ref = ERR_PTR(ret);
 745        goto error;
 746
 747        /* if we attempted to install a keyring, then it may have caused new
 748         * creds to be installed */
 749reget_creds:
 750        put_cred(cred);
 751        goto try_again;
 752}
 753
 754/*
 755 * Join the named keyring as the session keyring if possible else attempt to
 756 * create a new one of that name and join that.
 757 *
 758 * If the name is NULL, an empty anonymous keyring will be installed as the
 759 * session keyring.
 760 *
 761 * Named session keyrings are joined with a semaphore held to prevent the
 762 * keyrings from going away whilst the attempt is made to going them and also
 763 * to prevent a race in creating compatible session keyrings.
 764 */
 765long join_session_keyring(const char *name)
 766{
 767        const struct cred *old;
 768        struct cred *new;
 769        struct key *keyring;
 770        long ret, serial;
 771
 772        /* only permit this if there's a single thread in the thread group -
 773         * this avoids us having to adjust the creds on all threads and risking
 774         * ENOMEM */
 775        if (!current_is_single_threaded())
 776                return -EMLINK;
 777
 778        new = prepare_creds();
 779        if (!new)
 780                return -ENOMEM;
 781        old = current_cred();
 782
 783        /* if no name is provided, install an anonymous keyring */
 784        if (!name) {
 785                ret = install_session_keyring_to_cred(new, NULL);
 786                if (ret < 0)
 787                        goto error;
 788
 789                serial = new->tgcred->session_keyring->serial;
 790                ret = commit_creds(new);
 791                if (ret == 0)
 792                        ret = serial;
 793                goto okay;
 794        }
 795
 796        /* allow the user to join or create a named keyring */
 797        mutex_lock(&key_session_mutex);
 798
 799        /* look for an existing keyring of this name */
 800        keyring = find_keyring_by_name(name, false);
 801        if (PTR_ERR(keyring) == -ENOKEY) {
 802                /* not found - try and create a new one */
 803                keyring = keyring_alloc(name, old->uid, old->gid, old,
 804                                        KEY_ALLOC_IN_QUOTA, NULL);
 805                if (IS_ERR(keyring)) {
 806                        ret = PTR_ERR(keyring);
 807                        goto error2;
 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_to_cred(new, keyring);
 816        if (ret < 0)
 817                goto error2;
 818
 819        commit_creds(new);
 820        mutex_unlock(&key_session_mutex);
 821
 822        ret = keyring->serial;
 823        key_put(keyring);
 824okay:
 825        return ret;
 826
 827error2:
 828        mutex_unlock(&key_session_mutex);
 829error:
 830        abort_creds(new);
 831        return ret;
 832}
 833
 834/*
 835 * Replace a process's session keyring on behalf of one of its children when
 836 * the target  process is about to resume userspace execution.
 837 */
 838void key_change_session_keyring(struct callback_head *twork)
 839{
 840        const struct cred *old = current_cred();
 841        struct cred *new = container_of(twork, struct cred, rcu);
 842
 843        if (unlikely(current->flags & PF_EXITING)) {
 844                put_cred(new);
 845                return;
 846        }
 847
 848        new->  uid      = old->  uid;
 849        new-> euid      = old-> euid;
 850        new-> suid      = old-> suid;
 851        new->fsuid      = old->fsuid;
 852        new->  gid      = old->  gid;
 853        new-> egid      = old-> egid;
 854        new-> sgid      = old-> sgid;
 855        new->fsgid      = old->fsgid;
 856        new->user       = get_uid(old->user);
 857        new->user_ns    = get_user_ns(new->user_ns);
 858        new->group_info = get_group_info(old->group_info);
 859
 860        new->securebits = old->securebits;
 861        new->cap_inheritable    = old->cap_inheritable;
 862        new->cap_permitted      = old->cap_permitted;
 863        new->cap_effective      = old->cap_effective;
 864        new->cap_bset           = old->cap_bset;
 865
 866        new->jit_keyring        = old->jit_keyring;
 867        new->thread_keyring     = key_get(old->thread_keyring);
 868        new->tgcred->tgid       = old->tgcred->tgid;
 869        new->tgcred->process_keyring = key_get(old->tgcred->process_keyring);
 870
 871        security_transfer_creds(new, old);
 872
 873        commit_creds(new);
 874}
 875
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.