linux/security/keys/request_key.c
<<
>>
Prefs
   1/* Request a key from userspace
   2 *
   3 * Copyright (C) 2004-2007 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 * See Documentation/keys-request-key.txt
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/sched.h>
  16#include <linux/kmod.h>
  17#include <linux/err.h>
  18#include <linux/keyctl.h>
  19#include <linux/slab.h>
  20#include "internal.h"
  21
  22#define key_negative_timeout    60      /* default timeout on a negative key's existence */
  23
  24/*
  25 * wait_on_bit() sleep function for uninterruptible waiting
  26 */
  27static int key_wait_bit(void *flags)
  28{
  29        schedule();
  30        return 0;
  31}
  32
  33/*
  34 * wait_on_bit() sleep function for interruptible waiting
  35 */
  36static int key_wait_bit_intr(void *flags)
  37{
  38        schedule();
  39        return signal_pending(current) ? -ERESTARTSYS : 0;
  40}
  41
  42/*
  43 * call to complete the construction of a key
  44 */
  45void complete_request_key(struct key_construction *cons, int error)
  46{
  47        kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
  48
  49        if (error < 0)
  50                key_negate_and_link(cons->key, key_negative_timeout, NULL,
  51                                    cons->authkey);
  52        else
  53                key_revoke(cons->authkey);
  54
  55        key_put(cons->key);
  56        key_put(cons->authkey);
  57        kfree(cons);
  58}
  59EXPORT_SYMBOL(complete_request_key);
  60
  61static int umh_keys_init(struct subprocess_info *info)
  62{
  63        struct cred *cred = (struct cred*)current_cred();
  64        struct key *keyring = info->data;
  65        /*
  66         * This is called in context of freshly forked kthread before
  67         * kernel_execve(), we can just change our ->session_keyring.
  68         */
  69        return install_session_keyring_to_cred(cred, keyring);
  70}
  71
  72static void umh_keys_cleanup(struct subprocess_info *info)
  73{
  74        struct key *keyring = info->data;
  75        key_put(keyring);
  76}
  77
  78static int call_usermodehelper_keys(char *path, char **argv, char **envp,
  79                         struct key *session_keyring, enum umh_wait wait)
  80{
  81        gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
  82        struct subprocess_info *info =
  83                call_usermodehelper_setup(path, argv, envp, gfp_mask);
  84
  85        if (!info)
  86                return -ENOMEM;
  87
  88        call_usermodehelper_setfns(info, umh_keys_init, umh_keys_cleanup,
  89                                        key_get(session_keyring));
  90        return call_usermodehelper_exec(info, wait);
  91}
  92
  93/*
  94 * request userspace finish the construction of a key
  95 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
  96 */
  97static int call_sbin_request_key(struct key_construction *cons,
  98                                 const char *op,
  99                                 void *aux)
 100{
 101        const struct cred *cred = current_cred();
 102        key_serial_t prkey, sskey;
 103        struct key *key = cons->key, *authkey = cons->authkey, *keyring,
 104                *session;
 105        char *argv[9], *envp[3], uid_str[12], gid_str[12];
 106        char key_str[12], keyring_str[3][12];
 107        char desc[20];
 108        int ret, i;
 109
 110        kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
 111
 112        ret = install_user_keyrings();
 113        if (ret < 0)
 114                goto error_alloc;
 115
 116        /* allocate a new session keyring */
 117        sprintf(desc, "_req.%u", key->serial);
 118
 119        cred = get_current_cred();
 120        keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
 121                                KEY_ALLOC_QUOTA_OVERRUN, NULL);
 122        put_cred(cred);
 123        if (IS_ERR(keyring)) {
 124                ret = PTR_ERR(keyring);
 125                goto error_alloc;
 126        }
 127
 128        /* attach the auth key to the session keyring */
 129        ret = key_link(keyring, authkey);
 130        if (ret < 0)
 131                goto error_link;
 132
 133        /* record the UID and GID */
 134        sprintf(uid_str, "%d", cred->fsuid);
 135        sprintf(gid_str, "%d", cred->fsgid);
 136
 137        /* we say which key is under construction */
 138        sprintf(key_str, "%d", key->serial);
 139
 140        /* we specify the process's default keyrings */
 141        sprintf(keyring_str[0], "%d",
 142                cred->thread_keyring ? cred->thread_keyring->serial : 0);
 143
 144        prkey = 0;
 145        if (cred->tgcred->process_keyring)
 146                prkey = cred->tgcred->process_keyring->serial;
 147
 148        rcu_read_lock();
 149        session = rcu_dereference(cred->tgcred->session_keyring);
 150        if (!session)
 151                session = cred->user->session_keyring;
 152        sskey = session->serial;
 153        rcu_read_unlock();
 154
 155        sprintf(keyring_str[2], "%d", sskey);
 156
 157        /* set up a minimal environment */
 158        i = 0;
 159        envp[i++] = "HOME=/";
 160        envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 161        envp[i] = NULL;
 162
 163        /* set up the argument list */
 164        i = 0;
 165        argv[i++] = "/sbin/request-key";
 166        argv[i++] = (char *) op;
 167        argv[i++] = key_str;
 168        argv[i++] = uid_str;
 169        argv[i++] = gid_str;
 170        argv[i++] = keyring_str[0];
 171        argv[i++] = keyring_str[1];
 172        argv[i++] = keyring_str[2];
 173        argv[i] = NULL;
 174
 175        /* do it */
 176        ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
 177                                       UMH_WAIT_PROC);
 178        kdebug("usermode -> 0x%x", ret);
 179        if (ret >= 0) {
 180                /* ret is the exit/wait code */
 181                if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
 182                    key_validate(key) < 0)
 183                        ret = -ENOKEY;
 184                else
 185                        /* ignore any errors from userspace if the key was
 186                         * instantiated */
 187                        ret = 0;
 188        }
 189
 190error_link:
 191        key_put(keyring);
 192
 193error_alloc:
 194        complete_request_key(cons, ret);
 195        kleave(" = %d", ret);
 196        return ret;
 197}
 198
 199/*
 200 * call out to userspace for key construction
 201 * - we ignore program failure and go on key status instead
 202 */
 203static int construct_key(struct key *key, const void *callout_info,
 204                         size_t callout_len, void *aux,
 205                         struct key *dest_keyring)
 206{
 207        struct key_construction *cons;
 208        request_key_actor_t actor;
 209        struct key *authkey;
 210        int ret;
 211
 212        kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
 213
 214        cons = kmalloc(sizeof(*cons), GFP_KERNEL);
 215        if (!cons)
 216                return -ENOMEM;
 217
 218        /* allocate an authorisation key */
 219        authkey = request_key_auth_new(key, callout_info, callout_len,
 220                                       dest_keyring);
 221        if (IS_ERR(authkey)) {
 222                kfree(cons);
 223                ret = PTR_ERR(authkey);
 224                authkey = NULL;
 225        } else {
 226                cons->authkey = key_get(authkey);
 227                cons->key = key_get(key);
 228
 229                /* make the call */
 230                actor = call_sbin_request_key;
 231                if (key->type->request_key)
 232                        actor = key->type->request_key;
 233
 234                ret = actor(cons, "create", aux);
 235
 236                /* check that the actor called complete_request_key() prior to
 237                 * returning an error */
 238                WARN_ON(ret < 0 &&
 239                        !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
 240                key_put(authkey);
 241        }
 242
 243        kleave(" = %d", ret);
 244        return ret;
 245}
 246
 247/*
 248 * get the appropriate destination keyring for the request
 249 * - we return whatever keyring we select with an extra reference upon it which
 250 *   the caller must release
 251 */
 252static void construct_get_dest_keyring(struct key **_dest_keyring)
 253{
 254        struct request_key_auth *rka;
 255        const struct cred *cred = current_cred();
 256        struct key *dest_keyring = *_dest_keyring, *authkey;
 257
 258        kenter("%p", dest_keyring);
 259
 260        /* find the appropriate keyring */
 261        if (dest_keyring) {
 262                /* the caller supplied one */
 263                key_get(dest_keyring);
 264        } else {
 265                /* use a default keyring; falling through the cases until we
 266                 * find one that we actually have */
 267                switch (cred->jit_keyring) {
 268                case KEY_REQKEY_DEFL_DEFAULT:
 269                case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
 270                        if (cred->request_key_auth) {
 271                                authkey = cred->request_key_auth;
 272                                down_read(&authkey->sem);
 273                                rka = authkey->payload.data;
 274                                if (!test_bit(KEY_FLAG_REVOKED,
 275                                              &authkey->flags))
 276                                        dest_keyring =
 277                                                key_get(rka->dest_keyring);
 278                                up_read(&authkey->sem);
 279                                if (dest_keyring)
 280                                        break;
 281                        }
 282
 283                case KEY_REQKEY_DEFL_THREAD_KEYRING:
 284                        dest_keyring = key_get(cred->thread_keyring);
 285                        if (dest_keyring)
 286                                break;
 287
 288                case KEY_REQKEY_DEFL_PROCESS_KEYRING:
 289                        dest_keyring = key_get(cred->tgcred->process_keyring);
 290                        if (dest_keyring)
 291                                break;
 292
 293                case KEY_REQKEY_DEFL_SESSION_KEYRING:
 294                        rcu_read_lock();
 295                        dest_keyring = key_get(
 296                                rcu_dereference(cred->tgcred->session_keyring));
 297                        rcu_read_unlock();
 298
 299                        if (dest_keyring)
 300                                break;
 301
 302                case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
 303                        dest_keyring =
 304                                key_get(cred->user->session_keyring);
 305                        break;
 306
 307                case KEY_REQKEY_DEFL_USER_KEYRING:
 308                        dest_keyring = key_get(cred->user->uid_keyring);
 309                        break;
 310
 311                case KEY_REQKEY_DEFL_GROUP_KEYRING:
 312                default:
 313                        BUG();
 314                }
 315        }
 316
 317        *_dest_keyring = dest_keyring;
 318        kleave(" [dk %d]", key_serial(dest_keyring));
 319        return;
 320}
 321
 322/*
 323 * allocate a new key in under-construction state and attempt to link it in to
 324 * the requested place
 325 * - may return a key that's already under construction instead
 326 */
 327static int construct_alloc_key(struct key_type *type,
 328                               const char *description,
 329                               struct key *dest_keyring,
 330                               unsigned long flags,
 331                               struct key_user *user,
 332                               struct key **_key)
 333{
 334        struct keyring_list *prealloc;
 335        const struct cred *cred = current_cred();
 336        struct key *key;
 337        key_ref_t key_ref;
 338        int ret;
 339
 340        kenter("%s,%s,,,", type->name, description);
 341
 342        *_key = NULL;
 343        mutex_lock(&user->cons_lock);
 344
 345        key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
 346                        KEY_POS_ALL, flags);
 347        if (IS_ERR(key))
 348                goto alloc_failed;
 349
 350        set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 351
 352        if (dest_keyring) {
 353                ret = __key_link_begin(dest_keyring, type, description,
 354                                       &prealloc);
 355                if (ret < 0)
 356                        goto link_prealloc_failed;
 357        }
 358
 359        /* attach the key to the destination keyring under lock, but we do need
 360         * to do another check just in case someone beat us to it whilst we
 361         * waited for locks */
 362        mutex_lock(&key_construction_mutex);
 363
 364        key_ref = search_process_keyrings(type, description, type->match, cred);
 365        if (!IS_ERR(key_ref))
 366                goto key_already_present;
 367
 368        if (dest_keyring)
 369                __key_link(dest_keyring, key, &prealloc);
 370
 371        mutex_unlock(&key_construction_mutex);
 372        if (dest_keyring)
 373                __key_link_end(dest_keyring, type, prealloc);
 374        mutex_unlock(&user->cons_lock);
 375        *_key = key;
 376        kleave(" = 0 [%d]", key_serial(key));
 377        return 0;
 378
 379        /* the key is now present - we tell the caller that we found it by
 380         * returning -EINPROGRESS  */
 381key_already_present:
 382        key_put(key);
 383        mutex_unlock(&key_construction_mutex);
 384        key = key_ref_to_ptr(key_ref);
 385        if (dest_keyring) {
 386                ret = __key_link_check_live_key(dest_keyring, key);
 387                if (ret == 0)
 388                        __key_link(dest_keyring, key, &prealloc);
 389                __key_link_end(dest_keyring, type, prealloc);
 390                if (ret < 0)
 391                        goto link_check_failed;
 392        }
 393        mutex_unlock(&user->cons_lock);
 394        *_key = key;
 395        kleave(" = -EINPROGRESS [%d]", key_serial(key));
 396        return -EINPROGRESS;
 397
 398link_check_failed:
 399        mutex_unlock(&user->cons_lock);
 400        key_put(key);
 401        kleave(" = %d [linkcheck]", ret);
 402        return ret;
 403
 404link_prealloc_failed:
 405        up_write(&dest_keyring->sem);
 406        mutex_unlock(&user->cons_lock);
 407        kleave(" = %d [prelink]", ret);
 408        return ret;
 409
 410alloc_failed:
 411        mutex_unlock(&user->cons_lock);
 412        kleave(" = %ld", PTR_ERR(key));
 413        return PTR_ERR(key);
 414}
 415
 416/*
 417 * commence key construction
 418 */
 419static struct key *construct_key_and_link(struct key_type *type,
 420                                          const char *description,
 421                                          const char *callout_info,
 422                                          size_t callout_len,
 423                                          void *aux,
 424                                          struct key *dest_keyring,
 425                                          unsigned long flags)
 426{
 427        struct key_user *user;
 428        struct key *key;
 429        int ret;
 430
 431        kenter("");
 432
 433        user = key_user_lookup(current_fsuid(), current_user_ns());
 434        if (!user)
 435                return ERR_PTR(-ENOMEM);
 436
 437        construct_get_dest_keyring(&dest_keyring);
 438
 439        ret = construct_alloc_key(type, description, dest_keyring, flags, user,
 440                                  &key);
 441        key_user_put(user);
 442
 443        if (ret == 0) {
 444                ret = construct_key(key, callout_info, callout_len, aux,
 445                                    dest_keyring);
 446                if (ret < 0) {
 447                        kdebug("cons failed");
 448                        goto construction_failed;
 449                }
 450        } else if (ret == -EINPROGRESS) {
 451                ret = 0;
 452        } else {
 453                key = ERR_PTR(ret);
 454        }
 455
 456        key_put(dest_keyring);
 457        kleave(" = key %d", key_serial(key));
 458        return key;
 459
 460construction_failed:
 461        key_negate_and_link(key, key_negative_timeout, NULL, NULL);
 462        key_put(key);
 463        key_put(dest_keyring);
 464        kleave(" = %d", ret);
 465        return ERR_PTR(ret);
 466}
 467
 468/*
 469 * request a key
 470 * - search the process's keyrings
 471 * - check the list of keys being created or updated
 472 * - call out to userspace for a key if supplementary info was provided
 473 * - cache the key in an appropriate keyring
 474 */
 475struct key *request_key_and_link(struct key_type *type,
 476                                 const char *description,
 477                                 const void *callout_info,
 478                                 size_t callout_len,
 479                                 void *aux,
 480                                 struct key *dest_keyring,
 481                                 unsigned long flags)
 482{
 483        const struct cred *cred = current_cred();
 484        struct key *key;
 485        key_ref_t key_ref;
 486        int ret;
 487
 488        kenter("%s,%s,%p,%zu,%p,%p,%lx",
 489               type->name, description, callout_info, callout_len, aux,
 490               dest_keyring, flags);
 491
 492        /* search all the process keyrings for a key */
 493        key_ref = search_process_keyrings(type, description, type->match,
 494                                          cred);
 495
 496        if (!IS_ERR(key_ref)) {
 497                key = key_ref_to_ptr(key_ref);
 498                if (dest_keyring) {
 499                        construct_get_dest_keyring(&dest_keyring);
 500                        ret = key_link(dest_keyring, key);
 501                        key_put(dest_keyring);
 502                        if (ret < 0) {
 503                                key_put(key);
 504                                key = ERR_PTR(ret);
 505                                goto error;
 506                        }
 507                }
 508        } else if (PTR_ERR(key_ref) != -EAGAIN) {
 509                key = ERR_CAST(key_ref);
 510        } else  {
 511                /* the search failed, but the keyrings were searchable, so we
 512                 * should consult userspace if we can */
 513                key = ERR_PTR(-ENOKEY);
 514                if (!callout_info)
 515                        goto error;
 516
 517                key = construct_key_and_link(type, description, callout_info,
 518                                             callout_len, aux, dest_keyring,
 519                                             flags);
 520        }
 521
 522error:
 523        kleave(" = %p", key);
 524        return key;
 525}
 526
 527/*
 528 * wait for construction of a key to complete
 529 */
 530int wait_for_key_construction(struct key *key, bool intr)
 531{
 532        int ret;
 533
 534        ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
 535                          intr ? key_wait_bit_intr : key_wait_bit,
 536                          intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 537        if (ret < 0)
 538                return ret;
 539        return key_validate(key);
 540}
 541EXPORT_SYMBOL(wait_for_key_construction);
 542
 543/*
 544 * request a key
 545 * - search the process's keyrings
 546 * - check the list of keys being created or updated
 547 * - call out to userspace for a key if supplementary info was provided
 548 * - waits uninterruptible for creation to complete
 549 */
 550struct key *request_key(struct key_type *type,
 551                        const char *description,
 552                        const char *callout_info)
 553{
 554        struct key *key;
 555        size_t callout_len = 0;
 556        int ret;
 557
 558        if (callout_info)
 559                callout_len = strlen(callout_info);
 560        key = request_key_and_link(type, description, callout_info, callout_len,
 561                                   NULL, NULL, KEY_ALLOC_IN_QUOTA);
 562        if (!IS_ERR(key)) {
 563                ret = wait_for_key_construction(key, false);
 564                if (ret < 0) {
 565                        key_put(key);
 566                        return ERR_PTR(ret);
 567                }
 568        }
 569        return key;
 570}
 571EXPORT_SYMBOL(request_key);
 572
 573/*
 574 * request a key with auxiliary data for the upcaller
 575 * - search the process's keyrings
 576 * - check the list of keys being created or updated
 577 * - call out to userspace for a key if supplementary info was provided
 578 * - waits uninterruptible for creation to complete
 579 */
 580struct key *request_key_with_auxdata(struct key_type *type,
 581                                     const char *description,
 582                                     const void *callout_info,
 583                                     size_t callout_len,
 584                                     void *aux)
 585{
 586        struct key *key;
 587        int ret;
 588
 589        key = request_key_and_link(type, description, callout_info, callout_len,
 590                                   aux, NULL, KEY_ALLOC_IN_QUOTA);
 591        if (!IS_ERR(key)) {
 592                ret = wait_for_key_construction(key, false);
 593                if (ret < 0) {
 594                        key_put(key);
 595                        return ERR_PTR(ret);
 596                }
 597        }
 598        return key;
 599}
 600EXPORT_SYMBOL(request_key_with_auxdata);
 601
 602/*
 603 * request a key (allow async construction)
 604 * - search the process's keyrings
 605 * - check the list of keys being created or updated
 606 * - call out to userspace for a key if supplementary info was provided
 607 */
 608struct key *request_key_async(struct key_type *type,
 609                              const char *description,
 610                              const void *callout_info,
 611                              size_t callout_len)
 612{
 613        return request_key_and_link(type, description, callout_info,
 614                                    callout_len, NULL, NULL,
 615                                    KEY_ALLOC_IN_QUOTA);
 616}
 617EXPORT_SYMBOL(request_key_async);
 618
 619/*
 620 * request a key with auxiliary data for the upcaller (allow async construction)
 621 * - search the process's keyrings
 622 * - check the list of keys being created or updated
 623 * - call out to userspace for a key if supplementary info was provided
 624 */
 625struct key *request_key_async_with_auxdata(struct key_type *type,
 626                                           const char *description,
 627                                           const void *callout_info,
 628                                           size_t callout_len,
 629                                           void *aux)
 630{
 631        return request_key_and_link(type, description, callout_info,
 632                                    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
 633}
 634EXPORT_SYMBOL(request_key_async_with_auxdata);
 635
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.