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/*
  23 * wait_on_bit() sleep function for uninterruptible waiting
  24 */
  25static int key_wait_bit(void *flags)
  26{
  27        schedule();
  28        return 0;
  29}
  30
  31/*
  32 * wait_on_bit() sleep function for interruptible waiting
  33 */
  34static int key_wait_bit_intr(void *flags)
  35{
  36        schedule();
  37        return signal_pending(current) ? -ERESTARTSYS : 0;
  38}
  39
  40/*
  41 * call to complete the construction of a key
  42 */
  43void complete_request_key(struct key_construction *cons, int error)
  44{
  45        kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
  46
  47        if (error < 0)
  48                key_negate_and_link(cons->key, key_negative_timeout, NULL,
  49                                    cons->authkey);
  50        else
  51                key_revoke(cons->authkey);
  52
  53        key_put(cons->key);
  54        key_put(cons->authkey);
  55        kfree(cons);
  56}
  57EXPORT_SYMBOL(complete_request_key);
  58
  59/*
  60 * request userspace finish the construction of a key
  61 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
  62 */
  63static int call_sbin_request_key(struct key_construction *cons,
  64                                 const char *op,
  65                                 void *aux)
  66{
  67        struct task_struct *tsk = current;
  68        key_serial_t prkey, sskey;
  69        struct key *key = cons->key, *authkey = cons->authkey, *keyring;
  70        char *argv[9], *envp[3], uid_str[12], gid_str[12];
  71        char key_str[12], keyring_str[3][12];
  72        char desc[20];
  73        int ret, i;
  74
  75        kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
  76
  77        ret = install_user_keyrings(tsk);
  78        if (ret < 0)
  79                goto error_alloc;
  80
  81        /* allocate a new session keyring */
  82        sprintf(desc, "_req.%u", key->serial);
  83
  84        keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current,
  85                                KEY_ALLOC_QUOTA_OVERRUN, NULL);
  86        if (IS_ERR(keyring)) {
  87                ret = PTR_ERR(keyring);
  88                goto error_alloc;
  89        }
  90
  91        /* attach the auth key to the session keyring */
  92        ret = __key_link(keyring, authkey);
  93        if (ret < 0)
  94                goto error_link;
  95
  96        /* record the UID and GID */
  97        sprintf(uid_str, "%d", current->fsuid);
  98        sprintf(gid_str, "%d", current->fsgid);
  99
 100        /* we say which key is under construction */
 101        sprintf(key_str, "%d", key->serial);
 102
 103        /* we specify the process's default keyrings */
 104        sprintf(keyring_str[0], "%d",
 105                tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
 106
 107        prkey = 0;
 108        if (tsk->signal->process_keyring)
 109                prkey = tsk->signal->process_keyring->serial;
 110
 111        sprintf(keyring_str[1], "%d", prkey);
 112
 113        if (tsk->signal->session_keyring) {
 114                rcu_read_lock();
 115                sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
 116                rcu_read_unlock();
 117        } else {
 118                sskey = tsk->user->session_keyring->serial;
 119        }
 120
 121        sprintf(keyring_str[2], "%d", sskey);
 122
 123        /* set up a minimal environment */
 124        i = 0;
 125        envp[i++] = "HOME=/";
 126        envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 127        envp[i] = NULL;
 128
 129        /* set up the argument list */
 130        i = 0;
 131        argv[i++] = "/sbin/request-key";
 132        argv[i++] = (char *) op;
 133        argv[i++] = key_str;
 134        argv[i++] = uid_str;
 135        argv[i++] = gid_str;
 136        argv[i++] = keyring_str[0];
 137        argv[i++] = keyring_str[1];
 138        argv[i++] = keyring_str[2];
 139        argv[i] = NULL;
 140
 141        /* do it */
 142        ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
 143                                       UMH_WAIT_PROC);
 144        kdebug("usermode -> 0x%x", ret);
 145        if (ret >= 0) {
 146                /* ret is the exit/wait code */
 147                if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
 148                    key_validate(key) < 0)
 149                        ret = -ENOKEY;
 150                else
 151                        /* ignore any errors from userspace if the key was
 152                         * instantiated */
 153                        ret = 0;
 154        }
 155
 156error_link:
 157        key_put(keyring);
 158
 159error_alloc:
 160        kleave(" = %d", ret);
 161        complete_request_key(cons, ret);
 162        return ret;
 163}
 164
 165/*
 166 * call out to userspace for key construction
 167 * - we ignore program failure and go on key status instead
 168 */
 169static int construct_key(struct key *key, const void *callout_info,
 170                         size_t callout_len, void *aux)
 171{
 172        struct key_construction *cons;
 173        request_key_actor_t actor;
 174        struct key *authkey;
 175        int ret;
 176
 177        kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
 178
 179        cons = kmalloc(sizeof(*cons), GFP_KERNEL);
 180        if (!cons)
 181                return -ENOMEM;
 182
 183        /* allocate an authorisation key */
 184        authkey = request_key_auth_new(key, callout_info, callout_len);
 185        if (IS_ERR(authkey)) {
 186                kfree(cons);
 187                ret = PTR_ERR(authkey);
 188                authkey = NULL;
 189        } else {
 190                cons->authkey = key_get(authkey);
 191                cons->key = key_get(key);
 192
 193                /* make the call */
 194                actor = call_sbin_request_key;
 195                if (key->type->request_key)
 196                        actor = key->type->request_key;
 197
 198                ret = actor(cons, "create", aux);
 199
 200                /* check that the actor called complete_request_key() prior to
 201                 * returning an error */
 202                WARN_ON(ret < 0 &&
 203                        !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
 204                key_put(authkey);
 205        }
 206
 207        kleave(" = %d", ret);
 208        return ret;
 209}
 210
 211/*
 212 * link a key to the appropriate destination keyring
 213 * - the caller must hold a write lock on the destination keyring
 214 */
 215static void construct_key_make_link(struct key *key, struct key *dest_keyring)
 216{
 217        struct task_struct *tsk = current;
 218        struct key *drop = NULL;
 219
 220        kenter("{%d},%p", key->serial, dest_keyring);
 221
 222        /* find the appropriate keyring */
 223        if (!dest_keyring) {
 224                switch (tsk->jit_keyring) {
 225                case KEY_REQKEY_DEFL_DEFAULT:
 226                case KEY_REQKEY_DEFL_THREAD_KEYRING:
 227                        dest_keyring = tsk->thread_keyring;
 228                        if (dest_keyring)
 229                                break;
 230
 231                case KEY_REQKEY_DEFL_PROCESS_KEYRING:
 232                        dest_keyring = tsk->signal->process_keyring;
 233                        if (dest_keyring)
 234                                break;
 235
 236                case KEY_REQKEY_DEFL_SESSION_KEYRING:
 237                        rcu_read_lock();
 238                        dest_keyring = key_get(
 239                                rcu_dereference(tsk->signal->session_keyring));
 240                        rcu_read_unlock();
 241                        drop = dest_keyring;
 242
 243                        if (dest_keyring)
 244                                break;
 245
 246                case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
 247                        dest_keyring = tsk->user->session_keyring;
 248                        break;
 249
 250                case KEY_REQKEY_DEFL_USER_KEYRING:
 251                        dest_keyring = tsk->user->uid_keyring;
 252                        break;
 253
 254                case KEY_REQKEY_DEFL_GROUP_KEYRING:
 255                default:
 256                        BUG();
 257                }
 258        }
 259
 260        /* and attach the key to it */
 261        __key_link(dest_keyring, key);
 262        key_put(drop);
 263        kleave("");
 264}
 265
 266/*
 267 * allocate a new key in under-construction state and attempt to link it in to
 268 * the requested place
 269 * - may return a key that's already under construction instead
 270 */
 271static int construct_alloc_key(struct key_type *type,
 272                               const char *description,
 273                               struct key *dest_keyring,
 274                               unsigned long flags,
 275                               struct key_user *user,
 276                               struct key **_key)
 277{
 278        struct key *key;
 279        key_ref_t key_ref;
 280
 281        kenter("%s,%s,,,", type->name, description);
 282
 283        mutex_lock(&user->cons_lock);
 284
 285        key = key_alloc(type, description,
 286                        current->fsuid, current->fsgid, current, KEY_POS_ALL,
 287                        flags);
 288        if (IS_ERR(key))
 289                goto alloc_failed;
 290
 291        set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 292
 293        if (dest_keyring)
 294                down_write(&dest_keyring->sem);
 295
 296        /* attach the key to the destination keyring under lock, but we do need
 297         * to do another check just in case someone beat us to it whilst we
 298         * waited for locks */
 299        mutex_lock(&key_construction_mutex);
 300
 301        key_ref = search_process_keyrings(type, description, type->match,
 302                                          current);
 303        if (!IS_ERR(key_ref))
 304                goto key_already_present;
 305
 306        if (dest_keyring)
 307                construct_key_make_link(key, dest_keyring);
 308
 309        mutex_unlock(&key_construction_mutex);
 310        if (dest_keyring)
 311                up_write(&dest_keyring->sem);
 312        mutex_unlock(&user->cons_lock);
 313        *_key = key;
 314        kleave(" = 0 [%d]", key_serial(key));
 315        return 0;
 316
 317key_already_present:
 318        mutex_unlock(&key_construction_mutex);
 319        if (dest_keyring)
 320                up_write(&dest_keyring->sem);
 321        mutex_unlock(&user->cons_lock);
 322        key_put(key);
 323        *_key = key = key_ref_to_ptr(key_ref);
 324        kleave(" = -EINPROGRESS [%d]", key_serial(key));
 325        return -EINPROGRESS;
 326
 327alloc_failed:
 328        mutex_unlock(&user->cons_lock);
 329        *_key = NULL;
 330        kleave(" = %ld", PTR_ERR(key));
 331        return PTR_ERR(key);
 332}
 333
 334/*
 335 * commence key construction
 336 */
 337static struct key *construct_key_and_link(struct key_type *type,
 338                                          const char *description,
 339                                          const char *callout_info,
 340                                          size_t callout_len,
 341                                          void *aux,
 342                                          struct key *dest_keyring,
 343                                          unsigned long flags)
 344{
 345        struct key_user *user;
 346        struct key *key;
 347        int ret;
 348
 349        user = key_user_lookup(current->fsuid);
 350        if (!user)
 351                return ERR_PTR(-ENOMEM);
 352
 353        ret = construct_alloc_key(type, description, dest_keyring, flags, user,
 354                                  &key);
 355        key_user_put(user);
 356
 357        if (ret == 0) {
 358                ret = construct_key(key, callout_info, callout_len, aux);
 359                if (ret < 0)
 360                        goto construction_failed;
 361        }
 362
 363        return key;
 364
 365construction_failed:
 366        key_negate_and_link(key, key_negative_timeout, NULL, NULL);
 367        key_put(key);
 368        return ERR_PTR(ret);
 369}
 370
 371/*
 372 * request a key
 373 * - search the process's keyrings
 374 * - check the list of keys being created or updated
 375 * - call out to userspace for a key if supplementary info was provided
 376 * - cache the key in an appropriate keyring
 377 */
 378struct key *request_key_and_link(struct key_type *type,
 379                                 const char *description,
 380                                 const void *callout_info,
 381                                 size_t callout_len,
 382                                 void *aux,
 383                                 struct key *dest_keyring,
 384                                 unsigned long flags)
 385{
 386        struct key *key;
 387        key_ref_t key_ref;
 388
 389        kenter("%s,%s,%p,%zu,%p,%p,%lx",
 390               type->name, description, callout_info, callout_len, aux,
 391               dest_keyring, flags);
 392
 393        /* search all the process keyrings for a key */
 394        key_ref = search_process_keyrings(type, description, type->match,
 395                                          current);
 396
 397        if (!IS_ERR(key_ref)) {
 398                key = key_ref_to_ptr(key_ref);
 399        } else if (PTR_ERR(key_ref) != -EAGAIN) {
 400                key = ERR_CAST(key_ref);
 401        } else  {
 402                /* the search failed, but the keyrings were searchable, so we
 403                 * should consult userspace if we can */
 404                key = ERR_PTR(-ENOKEY);
 405                if (!callout_info)
 406                        goto error;
 407
 408                key = construct_key_and_link(type, description, callout_info,
 409                                             callout_len, aux, dest_keyring,
 410                                             flags);
 411        }
 412
 413error:
 414        kleave(" = %p", key);
 415        return key;
 416}
 417
 418/*
 419 * wait for construction of a key to complete
 420 */
 421int wait_for_key_construction(struct key *key, bool intr)
 422{
 423        int ret;
 424
 425        ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
 426                          intr ? key_wait_bit_intr : key_wait_bit,
 427                          intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 428        if (ret < 0)
 429                return ret;
 430        return key_validate(key);
 431}
 432EXPORT_SYMBOL(wait_for_key_construction);
 433
 434/*
 435 * request a key
 436 * - search the process's keyrings
 437 * - check the list of keys being created or updated
 438 * - call out to userspace for a key if supplementary info was provided
 439 * - waits uninterruptible for creation to complete
 440 */
 441struct key *request_key(struct key_type *type,
 442                        const char *description,
 443                        const char *callout_info)
 444{
 445        struct key *key;
 446        size_t callout_len = 0;
 447        int ret;
 448
 449        if (callout_info)
 450                callout_len = strlen(callout_info);
 451        key = request_key_and_link(type, description, callout_info, callout_len,
 452                                   NULL, NULL, KEY_ALLOC_IN_QUOTA);
 453        if (!IS_ERR(key)) {
 454                ret = wait_for_key_construction(key, false);
 455                if (ret < 0) {
 456                        key_put(key);
 457                        return ERR_PTR(ret);
 458                }
 459        }
 460        return key;
 461}
 462EXPORT_SYMBOL(request_key);
 463
 464/*
 465 * request a key with auxiliary data for the upcaller
 466 * - search the process's keyrings
 467 * - check the list of keys being created or updated
 468 * - call out to userspace for a key if supplementary info was provided
 469 * - waits uninterruptible for creation to complete
 470 */
 471struct key *request_key_with_auxdata(struct key_type *type,
 472                                     const char *description,
 473                                     const void *callout_info,
 474                                     size_t callout_len,
 475                                     void *aux)
 476{
 477        struct key *key;
 478        int ret;
 479
 480        key = request_key_and_link(type, description, callout_info, callout_len,
 481                                   aux, NULL, KEY_ALLOC_IN_QUOTA);
 482        if (!IS_ERR(key)) {
 483                ret = wait_for_key_construction(key, false);
 484                if (ret < 0) {
 485                        key_put(key);
 486                        return ERR_PTR(ret);
 487                }
 488        }
 489        return key;
 490}
 491EXPORT_SYMBOL(request_key_with_auxdata);
 492
 493/*
 494 * request a key (allow async construction)
 495 * - search the process's keyrings
 496 * - check the list of keys being created or updated
 497 * - call out to userspace for a key if supplementary info was provided
 498 */
 499struct key *request_key_async(struct key_type *type,
 500                              const char *description,
 501                              const void *callout_info,
 502                              size_t callout_len)
 503{
 504        return request_key_and_link(type, description, callout_info,
 505                                    callout_len, NULL, NULL,
 506                                    KEY_ALLOC_IN_QUOTA);
 507}
 508EXPORT_SYMBOL(request_key_async);
 509
 510/*
 511 * request a key with auxiliary data for the upcaller (allow async construction)
 512 * - search the process's keyrings
 513 * - check the list of keys being created or updated
 514 * - call out to userspace for a key if supplementary info was provided
 515 */
 516struct key *request_key_async_with_auxdata(struct key_type *type,
 517                                           const char *description,
 518                                           const void *callout_info,
 519                                           size_t callout_len,
 520                                           void *aux)
 521{
 522        return request_key_and_link(type, description, callout_info,
 523                                    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
 524}
 525EXPORT_SYMBOL(request_key_async_with_auxdata);
 526