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