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/security/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 * complete_request_key - Complete the construction of a key.
  44 * @cons: The key construction record.
  45 * @error: The success or failute of the construction.
  46 *
  47 * Complete the attempt to construct a key.  The key will be negated
  48 * if an error is indicated.  The authorisation key will be revoked
  49 * unconditionally.
  50 */
  51void complete_request_key(struct key_construction *cons, int error)
  52{
  53        kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
  54
  55        if (error < 0)
  56                key_negate_and_link(cons->key, key_negative_timeout, NULL,
  57                                    cons->authkey);
  58        else
  59                key_revoke(cons->authkey);
  60
  61        key_put(cons->key);
  62        key_put(cons->authkey);
  63        kfree(cons);
  64}
  65EXPORT_SYMBOL(complete_request_key);
  66
  67/*
  68 * Initialise a usermode helper that is going to have a specific session
  69 * keyring.
  70 *
  71 * This is called in context of freshly forked kthread before kernel_execve(),
  72 * so we can simply install the desired session_keyring at this point.
  73 */
  74static int umh_keys_init(struct subprocess_info *info, struct cred *cred)
  75{
  76        struct key *keyring = info->data;
  77
  78        return install_session_keyring_to_cred(cred, keyring);
  79}
  80
  81/*
  82 * Clean up a usermode helper with session keyring.
  83 */
  84static void umh_keys_cleanup(struct subprocess_info *info)
  85{
  86        struct key *keyring = info->data;
  87        key_put(keyring);
  88}
  89
  90/*
  91 * Call a usermode helper with a specific session keyring.
  92 */
  93static int call_usermodehelper_keys(char *path, char **argv, char **envp,
  94                                        struct key *session_keyring, int wait)
  95{
  96        return call_usermodehelper_fns(path, argv, envp, wait,
  97                                       umh_keys_init, umh_keys_cleanup,
  98                                       key_get(session_keyring));
  99}
 100
 101/*
 102 * Request userspace finish the construction of a key
 103 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
 104 */
 105static int call_sbin_request_key(struct key_construction *cons,
 106                                 const char *op,
 107                                 void *aux)
 108{
 109        const struct cred *cred = current_cred();
 110        key_serial_t prkey, sskey;
 111        struct key *key = cons->key, *authkey = cons->authkey, *keyring,
 112                *session;
 113        char *argv[9], *envp[3], uid_str[12], gid_str[12];
 114        char key_str[12], keyring_str[3][12];
 115        char desc[20];
 116        int ret, i;
 117
 118        kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
 119
 120        ret = install_user_keyrings();
 121        if (ret < 0)
 122                goto error_alloc;
 123
 124        /* allocate a new session keyring */
 125        sprintf(desc, "_req.%u", key->serial);
 126
 127        cred = get_current_cred();
 128        keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
 129                                KEY_ALLOC_QUOTA_OVERRUN, NULL);
 130        put_cred(cred);
 131        if (IS_ERR(keyring)) {
 132                ret = PTR_ERR(keyring);
 133                goto error_alloc;
 134        }
 135
 136        /* attach the auth key to the session keyring */
 137        ret = key_link(keyring, authkey);
 138        if (ret < 0)
 139                goto error_link;
 140
 141        /* record the UID and GID */
 142        sprintf(uid_str, "%d", cred->fsuid);
 143        sprintf(gid_str, "%d", cred->fsgid);
 144
 145        /* we say which key is under construction */
 146        sprintf(key_str, "%d", key->serial);
 147
 148        /* we specify the process's default keyrings */
 149        sprintf(keyring_str[0], "%d",
 150                cred->thread_keyring ? cred->thread_keyring->serial : 0);
 151
 152        prkey = 0;
 153        if (cred->tgcred->process_keyring)
 154                prkey = cred->tgcred->process_keyring->serial;
 155        sprintf(keyring_str[1], "%d", prkey);
 156
 157        rcu_read_lock();
 158        session = rcu_dereference(cred->tgcred->session_keyring);
 159        if (!session)
 160                session = cred->user->session_keyring;
 161        sskey = session->serial;
 162        rcu_read_unlock();
 163
 164        sprintf(keyring_str[2], "%d", sskey);
 165
 166        /* set up a minimal environment */
 167        i = 0;
 168        envp[i++] = "HOME=/";
 169        envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 170        envp[i] = NULL;
 171
 172        /* set up the argument list */
 173        i = 0;
 174        argv[i++] = "/sbin/request-key";
 175        argv[i++] = (char *) op;
 176        argv[i++] = key_str;
 177        argv[i++] = uid_str;
 178        argv[i++] = gid_str;
 179        argv[i++] = keyring_str[0];
 180        argv[i++] = keyring_str[1];
 181        argv[i++] = keyring_str[2];
 182        argv[i] = NULL;
 183
 184        /* do it */
 185        ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
 186                                       UMH_WAIT_PROC);
 187        kdebug("usermode -> 0x%x", ret);
 188        if (ret >= 0) {
 189                /* ret is the exit/wait code */
 190                if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
 191                    key_validate(key) < 0)
 192                        ret = -ENOKEY;
 193                else
 194                        /* ignore any errors from userspace if the key was
 195                         * instantiated */
 196                        ret = 0;
 197        }
 198
 199error_link:
 200        key_put(keyring);
 201
 202error_alloc:
 203        complete_request_key(cons, ret);
 204        kleave(" = %d", ret);
 205        return ret;
 206}
 207
 208/*
 209 * Call out to userspace for key construction.
 210 *
 211 * Program failure is ignored in favour of key status.
 212 */
 213static int construct_key(struct key *key, const void *callout_info,
 214                         size_t callout_len, void *aux,
 215                         struct key *dest_keyring)
 216{
 217        struct key_construction *cons;
 218        request_key_actor_t actor;
 219        struct key *authkey;
 220        int ret;
 221
 222        kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
 223
 224        cons = kmalloc(sizeof(*cons), GFP_KERNEL);
 225        if (!cons)
 226                return -ENOMEM;
 227
 228        /* allocate an authorisation key */
 229        authkey = request_key_auth_new(key, callout_info, callout_len,
 230                                       dest_keyring);
 231        if (IS_ERR(authkey)) {
 232                kfree(cons);
 233                ret = PTR_ERR(authkey);
 234                authkey = NULL;
 235        } else {
 236                cons->authkey = key_get(authkey);
 237                cons->key = key_get(key);
 238
 239                /* make the call */
 240                actor = call_sbin_request_key;
 241                if (key->type->request_key)
 242                        actor = key->type->request_key;
 243
 244                ret = actor(cons, "create", aux);
 245
 246                /* check that the actor called complete_request_key() prior to
 247                 * returning an error */
 248                WARN_ON(ret < 0 &&
 249                        !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
 250                key_put(authkey);
 251        }
 252
 253        kleave(" = %d", ret);
 254        return ret;
 255}
 256
 257/*
 258 * Get the appropriate destination keyring for the request.
 259 *
 260 * The keyring selected is returned with an extra reference upon it which the
 261 * caller must release.
 262 */
 263static void construct_get_dest_keyring(struct key **_dest_keyring)
 264{
 265        struct request_key_auth *rka;
 266        const struct cred *cred = current_cred();
 267        struct key *dest_keyring = *_dest_keyring, *authkey;
 268
 269        kenter("%p", dest_keyring);
 270
 271        /* find the appropriate keyring */
 272        if (dest_keyring) {
 273                /* the caller supplied one */
 274                key_get(dest_keyring);
 275        } else {
 276                /* use a default keyring; falling through the cases until we
 277                 * find one that we actually have */
 278                switch (cred->jit_keyring) {
 279                case KEY_REQKEY_DEFL_DEFAULT:
 280                case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
 281                        if (cred->request_key_auth) {
 282                                authkey = cred->request_key_auth;
 283                                down_read(&authkey->sem);
 284                                rka = authkey->payload.data;
 285                                if (!test_bit(KEY_FLAG_REVOKED,
 286                                              &authkey->flags))
 287                                        dest_keyring =
 288                                                key_get(rka->dest_keyring);
 289                                up_read(&authkey->sem);
 290                                if (dest_keyring)
 291                                        break;
 292                        }
 293
 294                case KEY_REQKEY_DEFL_THREAD_KEYRING:
 295                        dest_keyring = key_get(cred->thread_keyring);
 296                        if (dest_keyring)
 297                                break;
 298
 299                case KEY_REQKEY_DEFL_PROCESS_KEYRING:
 300                        dest_keyring = key_get(cred->tgcred->process_keyring);
 301                        if (dest_keyring)
 302                                break;
 303
 304                case KEY_REQKEY_DEFL_SESSION_KEYRING:
 305                        rcu_read_lock();
 306                        dest_keyring = key_get(
 307                                rcu_dereference(cred->tgcred->session_keyring));
 308                        rcu_read_unlock();
 309
 310                        if (dest_keyring)
 311                                break;
 312
 313                case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
 314                        dest_keyring =
 315                                key_get(cred->user->session_keyring);
 316                        break;
 317
 318                case KEY_REQKEY_DEFL_USER_KEYRING:
 319                        dest_keyring = key_get(cred->user->uid_keyring);
 320                        break;
 321
 322                case KEY_REQKEY_DEFL_GROUP_KEYRING:
 323                default:
 324                        BUG();
 325                }
 326        }
 327
 328        *_dest_keyring = dest_keyring;
 329        kleave(" [dk %d]", key_serial(dest_keyring));
 330        return;
 331}
 332
 333/*
 334 * Allocate a new key in under-construction state and attempt to link it in to
 335 * the requested keyring.
 336 *
 337 * May return a key that's already under construction instead if there was a
 338 * race between two thread calling request_key().
 339 */
 340static int construct_alloc_key(struct key_type *type,
 341                               const char *description,
 342                               struct key *dest_keyring,
 343                               unsigned long flags,
 344                               struct key_user *user,
 345                               struct key **_key)
 346{
 347        const struct cred *cred = current_cred();
 348        unsigned long prealloc;
 349        struct key *key;
 350        key_ref_t key_ref;
 351        int ret;
 352
 353        kenter("%s,%s,,,", type->name, description);
 354
 355        *_key = NULL;
 356        mutex_lock(&user->cons_lock);
 357
 358        key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
 359                        KEY_POS_ALL, flags);
 360        if (IS_ERR(key))
 361                goto alloc_failed;
 362
 363        set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 364
 365        if (dest_keyring) {
 366                ret = __key_link_begin(dest_keyring, type, description,
 367                                       &prealloc);
 368                if (ret < 0)
 369                        goto link_prealloc_failed;
 370        }
 371
 372        /* attach the key to the destination keyring under lock, but we do need
 373         * to do another check just in case someone beat us to it whilst we
 374         * waited for locks */
 375        mutex_lock(&key_construction_mutex);
 376
 377        key_ref = search_process_keyrings(type, description, type->match, cred);
 378        if (!IS_ERR(key_ref))
 379                goto key_already_present;
 380
 381        if (dest_keyring)
 382                __key_link(dest_keyring, key, &prealloc);
 383
 384        mutex_unlock(&key_construction_mutex);
 385        if (dest_keyring)
 386                __key_link_end(dest_keyring, type, prealloc);
 387        mutex_unlock(&user->cons_lock);
 388        *_key = key;
 389        kleave(" = 0 [%d]", key_serial(key));
 390        return 0;
 391
 392        /* the key is now present - we tell the caller that we found it by
 393         * returning -EINPROGRESS  */
 394key_already_present:
 395        key_put(key);
 396        mutex_unlock(&key_construction_mutex);
 397        key = key_ref_to_ptr(key_ref);
 398        if (dest_keyring) {
 399                ret = __key_link_check_live_key(dest_keyring, key);
 400                if (ret == 0)
 401                        __key_link(dest_keyring, key, &prealloc);
 402                __key_link_end(dest_keyring, type, prealloc);
 403                if (ret < 0)
 404                        goto link_check_failed;
 405        }
 406        mutex_unlock(&user->cons_lock);
 407        *_key = key;
 408        kleave(" = -EINPROGRESS [%d]", key_serial(key));
 409        return -EINPROGRESS;
 410
 411link_check_failed:
 412        mutex_unlock(&user->cons_lock);
 413        key_put(key);
 414        kleave(" = %d [linkcheck]", ret);
 415        return ret;
 416
 417link_prealloc_failed:
 418        mutex_unlock(&user->cons_lock);
 419        kleave(" = %d [prelink]", ret);
 420        return ret;
 421
 422alloc_failed:
 423        mutex_unlock(&user->cons_lock);
 424        kleave(" = %ld", PTR_ERR(key));
 425        return PTR_ERR(key);
 426}
 427
 428/*
 429 * Commence key construction.
 430 */
 431static struct key *construct_key_and_link(struct key_type *type,
 432                                          const char *description,
 433                                          const char *callout_info,
 434                                          size_t callout_len,
 435                                          void *aux,
 436                                          struct key *dest_keyring,
 437                                          unsigned long flags)
 438{
 439        struct key_user *user;
 440        struct key *key;
 441        int ret;
 442
 443        kenter("");
 444
 445        user = key_user_lookup(current_fsuid(), current_user_ns());
 446        if (!user)
 447                return ERR_PTR(-ENOMEM);
 448
 449        construct_get_dest_keyring(&dest_keyring);
 450
 451        ret = construct_alloc_key(type, description, dest_keyring, flags, user,
 452                                  &key);
 453        key_user_put(user);
 454
 455        if (ret == 0) {
 456                ret = construct_key(key, callout_info, callout_len, aux,
 457                                    dest_keyring);
 458                if (ret < 0) {
 459                        kdebug("cons failed");
 460                        goto construction_failed;
 461                }
 462        } else if (ret == -EINPROGRESS) {
 463                ret = 0;
 464        } else {
 465                goto couldnt_alloc_key;
 466        }
 467
 468        key_put(dest_keyring);
 469        kleave(" = key %d", key_serial(key));
 470        return key;
 471
 472construction_failed:
 473        key_negate_and_link(key, key_negative_timeout, NULL, NULL);
 474        key_put(key);
 475couldnt_alloc_key:
 476        key_put(dest_keyring);
 477        kleave(" = %d", ret);
 478        return ERR_PTR(ret);
 479}
 480
 481/**
 482 * request_key_and_link - Request a key and cache it in a keyring.
 483 * @type: The type of key we want.
 484 * @description: The searchable description of the key.
 485 * @callout_info: The data to pass to the instantiation upcall (or NULL).
 486 * @callout_len: The length of callout_info.
 487 * @aux: Auxiliary data for the upcall.
 488 * @dest_keyring: Where to cache the key.
 489 * @flags: Flags to key_alloc().
 490 *
 491 * A key matching the specified criteria is searched for in the process's
 492 * keyrings and returned with its usage count incremented if found.  Otherwise,
 493 * if callout_info is not NULL, a key will be allocated and some service
 494 * (probably in userspace) will be asked to instantiate it.
 495 *
 496 * If successfully found or created, the key will be linked to the destination
 497 * keyring if one is provided.
 498 *
 499 * Returns a pointer to the key if successful; -EACCES, -ENOKEY, -EKEYREVOKED
 500 * or -EKEYEXPIRED if an inaccessible, negative, revoked or expired key was
 501 * found; -ENOKEY if no key was found and no @callout_info was given; -EDQUOT
 502 * if insufficient key quota was available to create a new key; or -ENOMEM if
 503 * insufficient memory was available.
 504 *
 505 * If the returned key was created, then it may still be under construction,
 506 * and wait_for_key_construction() should be used to wait for that to complete.
 507 */
 508struct key *request_key_and_link(struct key_type *type,
 509                                 const char *description,
 510                                 const void *callout_info,
 511                                 size_t callout_len,
 512                                 void *aux,
 513                                 struct key *dest_keyring,
 514                                 unsigned long flags)
 515{
 516        const struct cred *cred = current_cred();
 517        struct key *key;
 518        key_ref_t key_ref;
 519        int ret;
 520
 521        kenter("%s,%s,%p,%zu,%p,%p,%lx",
 522               type->name, description, callout_info, callout_len, aux,
 523               dest_keyring, flags);
 524
 525        /* search all the process keyrings for a key */
 526        key_ref = search_process_keyrings(type, description, type->match, cred);
 527
 528        if (!IS_ERR(key_ref)) {
 529                key = key_ref_to_ptr(key_ref);
 530                if (dest_keyring) {
 531                        construct_get_dest_keyring(&dest_keyring);
 532                        ret = key_link(dest_keyring, key);
 533                        key_put(dest_keyring);
 534                        if (ret < 0) {
 535                                key_put(key);
 536                                key = ERR_PTR(ret);
 537                                goto error;
 538                        }
 539                }
 540        } else if (PTR_ERR(key_ref) != -EAGAIN) {
 541                key = ERR_CAST(key_ref);
 542        } else  {
 543                /* the search failed, but the keyrings were searchable, so we
 544                 * should consult userspace if we can */
 545                key = ERR_PTR(-ENOKEY);
 546                if (!callout_info)
 547                        goto error;
 548
 549                key = construct_key_and_link(type, description, callout_info,
 550                                             callout_len, aux, dest_keyring,
 551                                             flags);
 552        }
 553
 554error:
 555        kleave(" = %p", key);
 556        return key;
 557}
 558
 559/**
 560 * wait_for_key_construction - Wait for construction of a key to complete
 561 * @key: The key being waited for.
 562 * @intr: Whether to wait interruptibly.
 563 *
 564 * Wait for a key to finish being constructed.
 565 *
 566 * Returns 0 if successful; -ERESTARTSYS if the wait was interrupted; -ENOKEY
 567 * if the key was negated; or -EKEYREVOKED or -EKEYEXPIRED if the key was
 568 * revoked or expired.
 569 */
 570int wait_for_key_construction(struct key *key, bool intr)
 571{
 572        int ret;
 573
 574        ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
 575                          intr ? key_wait_bit_intr : key_wait_bit,
 576                          intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 577        if (ret < 0)
 578                return ret;
 579        if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
 580                return key->type_data.reject_error;
 581        return key_validate(key);
 582}
 583EXPORT_SYMBOL(wait_for_key_construction);
 584
 585/**
 586 * request_key - Request a key and wait for construction
 587 * @type: Type of key.
 588 * @description: The searchable description of the key.
 589 * @callout_info: The data to pass to the instantiation upcall (or NULL).
 590 *
 591 * As for request_key_and_link() except that it does not add the returned key
 592 * to a keyring if found, new keys are always allocated in the user's quota,
 593 * the callout_info must be a NUL-terminated string and no auxiliary data can
 594 * be passed.
 595 *
 596 * Furthermore, it then works as wait_for_key_construction() to wait for the
 597 * completion of keys undergoing construction with a non-interruptible wait.
 598 */
 599struct key *request_key(struct key_type *type,
 600                        const char *description,
 601                        const char *callout_info)
 602{
 603        struct key *key;
 604        size_t callout_len = 0;
 605        int ret;
 606
 607        if (callout_info)
 608                callout_len = strlen(callout_info);
 609        key = request_key_and_link(type, description, callout_info, callout_len,
 610                                   NULL, NULL, KEY_ALLOC_IN_QUOTA);
 611        if (!IS_ERR(key)) {
 612                ret = wait_for_key_construction(key, false);
 613                if (ret < 0) {
 614                        key_put(key);
 615                        return ERR_PTR(ret);
 616                }
 617        }
 618        return key;
 619}
 620EXPORT_SYMBOL(request_key);
 621
 622/**
 623 * request_key_with_auxdata - Request a key with auxiliary data for the upcaller
 624 * @type: The type of key we want.
 625 * @description: The searchable description of the key.
 626 * @callout_info: The data to pass to the instantiation upcall (or NULL).
 627 * @callout_len: The length of callout_info.
 628 * @aux: Auxiliary data for the upcall.
 629 *
 630 * As for request_key_and_link() except that it does not add the returned key
 631 * to a keyring if found and new keys are always allocated in the user's quota.
 632 *
 633 * Furthermore, it then works as wait_for_key_construction() to wait for the
 634 * completion of keys undergoing construction with a non-interruptible wait.
 635 */
 636struct key *request_key_with_auxdata(struct key_type *type,
 637                                     const char *description,
 638                                     const void *callout_info,
 639                                     size_t callout_len,
 640                                     void *aux)
 641{
 642        struct key *key;
 643        int ret;
 644
 645        key = request_key_and_link(type, description, callout_info, callout_len,
 646                                   aux, NULL, KEY_ALLOC_IN_QUOTA);
 647        if (!IS_ERR(key)) {
 648                ret = wait_for_key_construction(key, false);
 649                if (ret < 0) {
 650                        key_put(key);
 651                        return ERR_PTR(ret);
 652                }
 653        }
 654        return key;
 655}
 656EXPORT_SYMBOL(request_key_with_auxdata);
 657
 658/*
 659 * request_key_async - Request a key (allow async construction)
 660 * @type: Type of key.
 661 * @description: The searchable description of the key.
 662 * @callout_info: The data to pass to the instantiation upcall (or NULL).
 663 * @callout_len: The length of callout_info.
 664 *
 665 * As for request_key_and_link() except that it does not add the returned key
 666 * to a keyring if found, new keys are always allocated in the user's quota and
 667 * no auxiliary data can be passed.
 668 *
 669 * The caller should call wait_for_key_construction() to wait for the
 670 * completion of the returned key if it is still undergoing construction.
 671 */
 672struct key *request_key_async(struct key_type *type,
 673                              const char *description,
 674                              const void *callout_info,
 675                              size_t callout_len)
 676{
 677        return request_key_and_link(type, description, callout_info,
 678                                    callout_len, NULL, NULL,
 679                                    KEY_ALLOC_IN_QUOTA);
 680}
 681EXPORT_SYMBOL(request_key_async);
 682
 683/*
 684 * request a key with auxiliary data for the upcaller (allow async construction)
 685 * @type: Type of key.
 686 * @description: The searchable description of the key.
 687 * @callout_info: The data to pass to the instantiation upcall (or NULL).
 688 * @callout_len: The length of callout_info.
 689 * @aux: Auxiliary data for the upcall.
 690 *
 691 * As for request_key_and_link() except that it does not add the returned key
 692 * to a keyring if found and new keys are always allocated in the user's quota.
 693 *
 694 * The caller should call wait_for_key_construction() to wait for the
 695 * completion of the returned key if it is still undergoing construction.
 696 */
 697struct key *request_key_async_with_auxdata(struct key_type *type,
 698                                           const char *description,
 699                                           const void *callout_info,
 700                                           size_t callout_len,
 701                                           void *aux)
 702{
 703        return request_key_and_link(type, description, callout_info,
 704                                    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
 705}
 706EXPORT_SYMBOL(request_key_async_with_auxdata);
 707
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.