linux-bk/security/keys/keyctl.c
<<
>>
Prefs
   1/* keyctl.c: userspace keyctl operations
   2 *
   3 * Copyright (C) 2004 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/syscalls.h>
  17#include <linux/keyctl.h>
  18#include <linux/fs.h>
  19#include <linux/err.h>
  20#include <asm/uaccess.h>
  21#include "internal.h"
  22
  23/*****************************************************************************/
  24/*
  25 * extract the description of a new key from userspace and either add it as a
  26 * new key to the specified keyring or update a matching key in that keyring
  27 * - the keyring must be writable
  28 * - returns the new key's serial number
  29 * - implements add_key()
  30 */
  31asmlinkage long sys_add_key(const char __user *_type,
  32                            const char __user *_description,
  33                            const void __user *_payload,
  34                            size_t plen,
  35                            key_serial_t ringid)
  36{
  37        struct key *keyring, *key;
  38        char type[32], *description;
  39        void *payload;
  40        long dlen, ret;
  41
  42        ret = -EINVAL;
  43        if (plen > 32767)
  44                goto error;
  45
  46        /* draw all the data into kernel space */
  47        ret = strncpy_from_user(type, _type, sizeof(type) - 1);
  48        if (ret < 0)
  49                goto error;
  50        type[31] = '\0';
  51
  52        ret = -EFAULT;
  53        dlen = strnlen_user(_description, PAGE_SIZE - 1);
  54        if (dlen <= 0)
  55                goto error;
  56
  57        ret = -EINVAL;
  58        if (dlen > PAGE_SIZE - 1)
  59                goto error;
  60
  61        ret = -ENOMEM;
  62        description = kmalloc(dlen + 1, GFP_KERNEL);
  63        if (!description)
  64                goto error;
  65
  66        ret = -EFAULT;
  67        if (copy_from_user(description, _description, dlen + 1) != 0)
  68                goto error2;
  69
  70        /* pull the payload in if one was supplied */
  71        payload = NULL;
  72
  73        if (_payload) {
  74                ret = -ENOMEM;
  75                payload = kmalloc(plen, GFP_KERNEL);
  76                if (!payload)
  77                        goto error2;
  78
  79                ret = -EFAULT;
  80                if (copy_from_user(payload, _payload, plen) != 0)
  81                        goto error3;
  82        }
  83
  84        /* find the target keyring (which must be writable) */
  85        keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
  86        if (IS_ERR(keyring)) {
  87                ret = PTR_ERR(keyring);
  88                goto error3;
  89        }
  90
  91        /* create or update the requested key and add it to the target
  92         * keyring */
  93        key = key_create_or_update(keyring, type, description,
  94                                   payload, plen, 0);
  95        if (!IS_ERR(key)) {
  96                ret = key->serial;
  97                key_put(key);
  98        }
  99        else {
 100                ret = PTR_ERR(key);
 101        }
 102
 103        key_put(keyring);
 104 error3:
 105        kfree(payload);
 106 error2:
 107        kfree(description);
 108 error:
 109        return ret;
 110
 111} /* end sys_add_key() */
 112
 113/*****************************************************************************/
 114/*
 115 * search the process keyrings for a matching key
 116 * - nested keyrings may also be searched if they have Search permission
 117 * - if a key is found, it will be attached to the destination keyring if
 118 *   there's one specified
 119 * - /sbin/request-key will be invoked if _callout_info is non-NULL
 120 *   - the _callout_info string will be passed to /sbin/request-key
 121 *   - if the _callout_info string is empty, it will be rendered as "-"
 122 * - implements request_key()
 123 */
 124asmlinkage long sys_request_key(const char __user *_type,
 125                                const char __user *_description,
 126                                const char __user *_callout_info,
 127                                key_serial_t destringid)
 128{
 129        struct key_type *ktype;
 130        struct key *key, *dest;
 131        char type[32], *description, *callout_info;
 132        long dlen, ret;
 133
 134        /* pull the type into kernel space */
 135        ret = strncpy_from_user(type, _type, sizeof(type) - 1);
 136        if (ret < 0)
 137                goto error;
 138        type[31] = '\0';
 139
 140        /* pull the description into kernel space */
 141        ret = -EFAULT;
 142        dlen = strnlen_user(_description, PAGE_SIZE - 1);
 143        if (dlen <= 0)
 144                goto error;
 145
 146        ret = -EINVAL;
 147        if (dlen > PAGE_SIZE - 1)
 148                goto error;
 149
 150        ret = -ENOMEM;
 151        description = kmalloc(dlen + 1, GFP_KERNEL);
 152        if (!description)
 153                goto error;
 154
 155        ret = -EFAULT;
 156        if (copy_from_user(description, _description, dlen + 1) != 0)
 157                goto error2;
 158
 159        /* pull the callout info into kernel space */
 160        callout_info = NULL;
 161        if (_callout_info) {
 162                ret = -EFAULT;
 163                dlen = strnlen_user(_callout_info, PAGE_SIZE - 1);
 164                if (dlen <= 0)
 165                        goto error2;
 166
 167                ret = -EINVAL;
 168                if (dlen > PAGE_SIZE - 1)
 169                        goto error2;
 170
 171                ret = -ENOMEM;
 172                callout_info = kmalloc(dlen + 1, GFP_KERNEL);
 173                if (!callout_info)
 174                        goto error2;
 175
 176                ret = -EFAULT;
 177                if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0)
 178                        goto error3;
 179        }
 180
 181        /* get the destination keyring if specified */
 182        dest = NULL;
 183        if (destringid) {
 184                dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
 185                if (IS_ERR(dest)) {
 186                        ret = PTR_ERR(dest);
 187                        goto error3;
 188                }
 189        }
 190
 191        /* find the key type */
 192        ktype = key_type_lookup(type);
 193        if (IS_ERR(ktype)) {
 194                ret = PTR_ERR(ktype);
 195                goto error4;
 196        }
 197
 198        /* do the search */
 199        key = request_key(ktype, description, callout_info);
 200        if (IS_ERR(key)) {
 201                ret = PTR_ERR(key);
 202                goto error5;
 203        }
 204
 205        /* link the resulting key to the destination keyring */
 206        if (dest) {
 207                ret = key_link(dest, key);
 208                if (ret < 0)
 209                        goto error6;
 210        }
 211
 212        ret = key->serial;
 213
 214 error6:
 215        key_put(key);
 216 error5:
 217        key_type_put(ktype);
 218 error4:
 219        key_put(dest);
 220 error3:
 221        kfree(callout_info);
 222 error2:
 223        kfree(description);
 224 error:
 225        return ret;
 226
 227} /* end sys_request_key() */
 228
 229/*****************************************************************************/
 230/*
 231 * get the ID of the specified process keyring
 232 * - the keyring must have search permission to be found
 233 * - implements keyctl(KEYCTL_GET_KEYRING_ID)
 234 */
 235long keyctl_get_keyring_ID(key_serial_t id, int create)
 236{
 237        struct key *key;
 238        long ret;
 239
 240        key = lookup_user_key(id, create, 0, KEY_SEARCH);
 241        if (IS_ERR(key)) {
 242                ret = PTR_ERR(key);
 243                goto error;
 244        }
 245
 246        ret = key->serial;
 247        key_put(key);
 248 error:
 249        return ret;
 250
 251} /* end keyctl_get_keyring_ID() */
 252
 253/*****************************************************************************/
 254/*
 255 * join the session keyring
 256 * - implements keyctl(KEYCTL_JOIN_SESSION_KEYRING)
 257 */
 258long keyctl_join_session_keyring(const char __user *_name)
 259{
 260        char *name;
 261        long nlen, ret;
 262
 263        /* fetch the name from userspace */
 264        name = NULL;
 265        if (_name) {
 266                ret = -EFAULT;
 267                nlen = strnlen_user(_name, PAGE_SIZE - 1);
 268                if (nlen <= 0)
 269                        goto error;
 270
 271                ret = -EINVAL;
 272                if (nlen > PAGE_SIZE - 1)
 273                        goto error;
 274
 275                ret = -ENOMEM;
 276                name = kmalloc(nlen + 1, GFP_KERNEL);
 277                if (!name)
 278                        goto error;
 279
 280                ret = -EFAULT;
 281                if (copy_from_user(name, _name, nlen + 1) != 0)
 282                        goto error2;
 283        }
 284
 285        /* join the session */
 286        ret = join_session_keyring(name);
 287
 288 error2:
 289        kfree(name);
 290 error:
 291        return ret;
 292
 293} /* end keyctl_join_session_keyring() */
 294
 295/*****************************************************************************/
 296/*
 297 * update a key's data payload
 298 * - the key must be writable
 299 * - implements keyctl(KEYCTL_UPDATE)
 300 */
 301long keyctl_update_key(key_serial_t id,
 302                       const void __user *_payload,
 303                       size_t plen)
 304{
 305        struct key *key;
 306        void *payload;
 307        long ret;
 308
 309        ret = -EINVAL;
 310        if (plen > PAGE_SIZE)
 311                goto error;
 312
 313        /* pull the payload in if one was supplied */
 314        payload = NULL;
 315        if (_payload) {
 316                ret = -ENOMEM;
 317                payload = kmalloc(plen, GFP_KERNEL);
 318                if (!payload)
 319                        goto error;
 320
 321                ret = -EFAULT;
 322                if (copy_from_user(payload, _payload, plen) != 0)
 323                        goto error2;
 324        }
 325
 326        /* find the target key (which must be writable) */
 327        key = lookup_user_key(id, 0, 0, KEY_WRITE);
 328        if (IS_ERR(key)) {
 329                ret = PTR_ERR(key);
 330                goto error2;
 331        }
 332
 333        /* update the key */
 334        ret = key_update(key, payload, plen);
 335
 336        key_put(key);
 337 error2:
 338        kfree(payload);
 339 error:
 340        return ret;
 341
 342} /* end keyctl_update_key() */
 343
 344/*****************************************************************************/
 345/*
 346 * revoke a key
 347 * - the key must be writable
 348 * - implements keyctl(KEYCTL_REVOKE)
 349 */
 350long keyctl_revoke_key(key_serial_t id)
 351{
 352        struct key *key;
 353        long ret;
 354
 355        key = lookup_user_key(id, 0, 0, KEY_WRITE);
 356        if (IS_ERR(key)) {
 357                ret = PTR_ERR(key);
 358                goto error;
 359        }
 360
 361        key_revoke(key);
 362        ret = 0;
 363
 364        key_put(key);
 365 error:
 366        return 0;
 367
 368} /* end keyctl_revoke_key() */
 369
 370/*****************************************************************************/
 371/*
 372 * clear the specified process keyring
 373 * - the keyring must be writable
 374 * - implements keyctl(KEYCTL_CLEAR)
 375 */
 376long keyctl_keyring_clear(key_serial_t ringid)
 377{
 378        struct key *keyring;
 379        long ret;
 380
 381        keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
 382        if (IS_ERR(keyring)) {
 383                ret = PTR_ERR(keyring);
 384                goto error;
 385        }
 386
 387        ret = keyring_clear(keyring);
 388
 389        key_put(keyring);
 390 error:
 391        return ret;
 392
 393} /* end keyctl_keyring_clear() */
 394
 395/*****************************************************************************/
 396/*
 397 * link a key into a keyring
 398 * - the keyring must be writable
 399 * - the key must be linkable
 400 * - implements keyctl(KEYCTL_LINK)
 401 */
 402long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
 403{
 404        struct key *keyring, *key;
 405        long ret;
 406
 407        keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
 408        if (IS_ERR(keyring)) {
 409                ret = PTR_ERR(keyring);
 410                goto error;
 411        }
 412
 413        key = lookup_user_key(id, 1, 0, KEY_LINK);
 414        if (IS_ERR(key)) {
 415                ret = PTR_ERR(key);
 416                goto error2;
 417        }
 418
 419        ret = key_link(keyring, key);
 420
 421        key_put(key);
 422 error2:
 423        key_put(keyring);
 424 error:
 425        return ret;
 426
 427} /* end keyctl_keyring_link() */
 428
 429/*****************************************************************************/
 430/*
 431 * unlink the first attachment of a key from a keyring
 432 * - the keyring must be writable
 433 * - we don't need any permissions on the key
 434 * - implements keyctl(KEYCTL_UNLINK)
 435 */
 436long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
 437{
 438        struct key *keyring, *key;
 439        long ret;
 440
 441        keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE);
 442        if (IS_ERR(keyring)) {
 443                ret = PTR_ERR(keyring);
 444                goto error;
 445        }
 446
 447        key = lookup_user_key(id, 0, 0, 0);
 448        if (IS_ERR(key)) {
 449                ret = PTR_ERR(key);
 450                goto error2;
 451        }
 452
 453        ret = key_unlink(keyring, key);
 454
 455        key_put(key);
 456 error2:
 457        key_put(keyring);
 458 error:
 459        return ret;
 460
 461} /* end keyctl_keyring_unlink() */
 462
 463/*****************************************************************************/
 464/*
 465 * describe a user key
 466 * - the key must have view permission
 467 * - if there's a buffer, we place up to buflen bytes of data into it
 468 * - unless there's an error, we return the amount of description available,
 469 *   irrespective of how much we may have copied
 470 * - the description is formatted thus:
 471 *      type;uid;gid;perm;description<NUL>
 472 * - implements keyctl(KEYCTL_DESCRIBE)
 473 */
 474long keyctl_describe_key(key_serial_t keyid,
 475                         char __user *buffer,
 476                         size_t buflen)
 477{
 478        struct key *key;
 479        char *tmpbuf;
 480        long ret;
 481
 482        key = lookup_user_key(keyid, 0, 1, KEY_VIEW);
 483        if (IS_ERR(key)) {
 484                ret = PTR_ERR(key);
 485                goto error;
 486        }
 487
 488        /* calculate how much description we're going to return */
 489        ret = -ENOMEM;
 490        tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 491        if (!tmpbuf)
 492                goto error2;
 493
 494        ret = snprintf(tmpbuf, PAGE_SIZE - 1,
 495                       "%s;%d;%d;%06x;%s",
 496                       key->type->name,
 497                       key->uid,
 498                       key->gid,
 499                       key->perm,
 500                       key->description ? key->description :""
 501                       );
 502
 503        /* include a NUL char at the end of the data */
 504        if (ret > PAGE_SIZE - 1)
 505                ret = PAGE_SIZE - 1;
 506        tmpbuf[ret] = 0;
 507        ret++;
 508
 509        /* consider returning the data */
 510        if (buffer && buflen > 0) {
 511                if (buflen > ret)
 512                        buflen = ret;
 513
 514                if (copy_to_user(buffer, tmpbuf, buflen) != 0)
 515                        ret = -EFAULT;
 516        }
 517
 518        kfree(tmpbuf);
 519 error2:
 520        key_put(key);
 521 error:
 522        return ret;
 523
 524} /* end keyctl_describe_key() */
 525
 526/*****************************************************************************/
 527/*
 528 * search the specified keyring for a matching key
 529 * - the start keyring must be searchable
 530 * - nested keyrings may also be searched if they are searchable
 531 * - only keys with search permission may be found
 532 * - if a key is found, it will be attached to the destination keyring if
 533 *   there's one specified
 534 * - implements keyctl(KEYCTL_SEARCH)
 535 */
 536long keyctl_keyring_search(key_serial_t ringid,
 537                           const char __user *_type,
 538                           const char __user *_description,
 539                           key_serial_t destringid)
 540{
 541        struct key_type *ktype;
 542        struct key *keyring, *key, *dest;
 543        char type[32], *description;
 544        long dlen, ret;
 545
 546        /* pull the type and description into kernel space */
 547        ret = strncpy_from_user(type, _type, sizeof(type) - 1);
 548        if (ret < 0)
 549                goto error;
 550        type[31] = '\0';
 551
 552        ret = -EFAULT;
 553        dlen = strnlen_user(_description, PAGE_SIZE - 1);
 554        if (dlen <= 0)
 555                goto error;
 556
 557        ret = -EINVAL;
 558        if (dlen > PAGE_SIZE - 1)
 559                goto error;
 560
 561        ret = -ENOMEM;
 562        description = kmalloc(dlen + 1, GFP_KERNEL);
 563        if (!description)
 564                goto error;
 565
 566        ret = -EFAULT;
 567        if (copy_from_user(description, _description, dlen + 1) != 0)
 568                goto error2;
 569
 570        /* get the keyring at which to begin the search */
 571        keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH);
 572        if (IS_ERR(keyring)) {
 573                ret = PTR_ERR(keyring);
 574                goto error2;
 575        }
 576
 577        /* get the destination keyring if specified */
 578        dest = NULL;
 579        if (destringid) {
 580                dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
 581                if (IS_ERR(dest)) {
 582                        ret = PTR_ERR(dest);
 583                        goto error3;
 584                }
 585        }
 586
 587        /* find the key type */
 588        ktype = key_type_lookup(type);
 589        if (IS_ERR(ktype)) {
 590                ret = PTR_ERR(ktype);
 591                goto error4;
 592        }
 593
 594        /* do the search */
 595        key = keyring_search(keyring, ktype, description);
 596        if (IS_ERR(key)) {
 597                ret = PTR_ERR(key);
 598
 599                /* treat lack or presence of a negative key the same */
 600                if (ret == -EAGAIN)
 601                        ret = -ENOKEY;
 602                goto error5;
 603        }
 604
 605        /* link the resulting key to the destination keyring if we can */
 606        if (dest) {
 607                ret = -EACCES;
 608                if (!key_permission(key, KEY_LINK))
 609                        goto error6;
 610
 611                ret = key_link(dest, key);
 612                if (ret < 0)
 613                        goto error6;
 614        }
 615
 616        ret = key->serial;
 617
 618 error6:
 619        key_put(key);
 620 error5:
 621        key_type_put(ktype);
 622 error4:
 623        key_put(dest);
 624 error3:
 625        key_put(keyring);
 626 error2:
 627        kfree(description);
 628 error:
 629        return ret;
 630
 631} /* end keyctl_keyring_search() */
 632
 633/*****************************************************************************/
 634/*
 635 * see if the key we're looking at is the target key
 636 */
 637static int keyctl_read_key_same(const struct key *key, const void *target)
 638{
 639        return key == target;
 640
 641} /* end keyctl_read_key_same() */
 642
 643/*****************************************************************************/
 644/*
 645 * read a user key's payload
 646 * - the keyring must be readable or the key must be searchable from the
 647 *   process's keyrings
 648 * - if there's a buffer, we place up to buflen bytes of data into it
 649 * - unless there's an error, we return the amount of data in the key,
 650 *   irrespective of how much we may have copied
 651 * - implements keyctl(KEYCTL_READ)
 652 */
 653long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
 654{
 655        struct key *key, *skey;
 656        long ret;
 657
 658        /* find the key first */
 659        key = lookup_user_key(keyid, 0, 0, 0);
 660        if (!IS_ERR(key)) {
 661                /* see if we can read it directly */
 662                if (key_permission(key, KEY_READ))
 663                        goto can_read_key;
 664
 665                /* can't; see if it's searchable from this process's
 666                 * keyrings */
 667                ret = -ENOKEY;
 668                if (key_permission(key, KEY_SEARCH)) {
 669                        /* okay - we do have search permission on the key
 670                         * itself, but do we have the key? */
 671                        skey = search_process_keyrings_aux(key->type, key,
 672                                                           keyctl_read_key_same);
 673                        if (!IS_ERR(skey))
 674                                goto can_read_key2;
 675                }
 676
 677                goto error2;
 678        }
 679
 680        ret = -ENOKEY;
 681        goto error;
 682
 683        /* the key is probably readable - now try to read it */
 684 can_read_key2:
 685        key_put(skey);
 686 can_read_key:
 687        ret = key_validate(key);
 688        if (ret == 0) {
 689                ret = -EOPNOTSUPP;
 690                if (key->type->read) {
 691                        /* read the data with the semaphore held (since we
 692                         * might sleep) */
 693                        down_read(&key->sem);
 694                        ret = key->type->read(key, buffer, buflen);
 695                        up_read(&key->sem);
 696                }
 697        }
 698
 699 error2:
 700        key_put(key);
 701 error:
 702        return ret;
 703
 704} /* end keyctl_read_key() */
 705
 706/*****************************************************************************/
 707/*
 708 * change the ownership of a key
 709 * - the keyring owned by the changer
 710 * - if the uid or gid is -1, then that parameter is not changed
 711 * - implements keyctl(KEYCTL_CHOWN)
 712 */
 713long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
 714{
 715        struct key *key;
 716        long ret;
 717
 718        ret = 0;
 719        if (uid == (uid_t) -1 && gid == (gid_t) -1)
 720                goto error;
 721
 722        key = lookup_user_key(id, 1, 1, 0);
 723        if (IS_ERR(key)) {
 724                ret = PTR_ERR(key);
 725                goto error;
 726        }
 727
 728        /* make the changes with the locks held to prevent chown/chown races */
 729        ret = -EACCES;
 730        down_write(&key->sem);
 731        write_lock(&key->lock);
 732
 733        if (!capable(CAP_SYS_ADMIN)) {
 734                /* only the sysadmin can chown a key to some other UID */
 735                if (uid != (uid_t) -1 && key->uid != uid)
 736                        goto no_access;
 737
 738                /* only the sysadmin can set the key's GID to a group other
 739                 * than one of those that the current process subscribes to */
 740                if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid))
 741                        goto no_access;
 742        }
 743
 744        /* change the UID (have to update the quotas) */
 745        if (uid != (uid_t) -1 && uid != key->uid) {
 746                /* don't support UID changing yet */
 747                ret = -EOPNOTSUPP;
 748                goto no_access;
 749        }
 750
 751        /* change the GID */
 752        if (gid != (gid_t) -1)
 753                key->gid = gid;
 754
 755        ret = 0;
 756
 757 no_access:
 758        write_unlock(&key->lock);
 759        up_write(&key->sem);
 760        key_put(key);
 761 error:
 762        return ret;
 763
 764} /* end keyctl_chown_key() */
 765
 766/*****************************************************************************/
 767/*
 768 * change the permission mask on a key
 769 * - the keyring owned by the changer
 770 * - implements keyctl(KEYCTL_SETPERM)
 771 */
 772long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
 773{
 774        struct key *key;
 775        long ret;
 776
 777        ret = -EINVAL;
 778        if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
 779                goto error;
 780
 781        key = lookup_user_key(id, 1, 1, 0);
 782        if (IS_ERR(key)) {
 783                ret = PTR_ERR(key);
 784                goto error;
 785        }
 786
 787        /* make the changes with the locks held to prevent chown/chmod
 788         * races */
 789        ret = -EACCES;
 790        down_write(&key->sem);
 791        write_lock(&key->lock);
 792
 793        /* if we're not the sysadmin, we can only chmod a key that we
 794         * own */
 795        if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid)
 796                goto no_access;
 797
 798        /* changing the permissions mask */
 799        key->perm = perm;
 800        ret = 0;
 801
 802 no_access:
 803        write_unlock(&key->lock);
 804        up_write(&key->sem);
 805        key_put(key);
 806 error:
 807        return ret;
 808
 809} /* end keyctl_setperm_key() */
 810
 811/*****************************************************************************/
 812/*
 813 * instantiate the key with the specified payload, and, if one is given, link
 814 * the key into the keyring
 815 */
 816long keyctl_instantiate_key(key_serial_t id,
 817                            const void __user *_payload,
 818                            size_t plen,
 819                            key_serial_t ringid)
 820{
 821        struct key *key, *keyring;
 822        void *payload;
 823        long ret;
 824
 825        ret = -EINVAL;
 826        if (plen > 32767)
 827                goto error;
 828
 829        /* pull the payload in if one was supplied */
 830        payload = NULL;
 831
 832        if (_payload) {
 833                ret = -ENOMEM;
 834                payload = kmalloc(plen, GFP_KERNEL);
 835                if (!payload)
 836                        goto error;
 837
 838                ret = -EFAULT;
 839                if (copy_from_user(payload, _payload, plen) != 0)
 840                        goto error2;
 841        }
 842
 843        /* find the target key (which must be writable) */
 844        key = lookup_user_key(id, 0, 1, KEY_WRITE);
 845        if (IS_ERR(key)) {
 846                ret = PTR_ERR(key);
 847                goto error2;
 848        }
 849
 850        /* find the destination keyring if present (which must also be
 851         * writable) */
 852        keyring = NULL;
 853        if (ringid) {
 854                keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
 855                if (IS_ERR(keyring)) {
 856                        ret = PTR_ERR(keyring);
 857                        goto error3;
 858                }
 859        }
 860
 861        /* instantiate the key and link it into a keyring */
 862        ret = key_instantiate_and_link(key, payload, plen, keyring);
 863
 864        key_put(keyring);
 865 error3:
 866        key_put(key);
 867 error2:
 868        kfree(payload);
 869 error:
 870        return ret;
 871
 872} /* end keyctl_instantiate_key() */
 873
 874/*****************************************************************************/
 875/*
 876 * negatively instantiate the key with the given timeout (in seconds), and, if
 877 * one is given, link the key into the keyring
 878 */
 879long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
 880{
 881        struct key *key, *keyring;
 882        long ret;
 883
 884        /* find the target key (which must be writable) */
 885        key = lookup_user_key(id, 0, 1, KEY_WRITE);
 886        if (IS_ERR(key)) {
 887                ret = PTR_ERR(key);
 888                goto error;
 889        }
 890
 891        /* find the destination keyring if present (which must also be
 892         * writable) */
 893        keyring = NULL;
 894        if (ringid) {
 895                keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
 896                if (IS_ERR(keyring)) {
 897                        ret = PTR_ERR(keyring);
 898                        goto error2;
 899                }
 900        }
 901
 902        /* instantiate the key and link it into a keyring */
 903        ret = key_negate_and_link(key, timeout, keyring);
 904
 905        key_put(keyring);
 906 error2:
 907        key_put(key);
 908 error:
 909        return ret;
 910
 911} /* end keyctl_negate_key() */
 912
 913/*****************************************************************************/
 914/*
 915 * the key control system call
 916 */
 917asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
 918                           unsigned long arg4, unsigned long arg5)
 919{
 920        switch (option) {
 921        case KEYCTL_GET_KEYRING_ID:
 922                return keyctl_get_keyring_ID((key_serial_t) arg2,
 923                                             (int) arg3);
 924
 925        case KEYCTL_JOIN_SESSION_KEYRING:
 926                return keyctl_join_session_keyring((const char __user *) arg2);
 927
 928        case KEYCTL_UPDATE:
 929                return keyctl_update_key((key_serial_t) arg2,
 930                                         (const void __user *) arg3,
 931                                         (size_t) arg4);
 932
 933        case KEYCTL_REVOKE:
 934                return keyctl_revoke_key((key_serial_t) arg2);
 935
 936        case KEYCTL_DESCRIBE:
 937                return keyctl_describe_key((key_serial_t) arg2,
 938                                           (char __user *) arg3,
 939                                           (unsigned) arg4);
 940
 941        case KEYCTL_CLEAR:
 942                return keyctl_keyring_clear((key_serial_t) arg2);
 943
 944        case KEYCTL_LINK:
 945                return keyctl_keyring_link((key_serial_t) arg2,
 946                                           (key_serial_t) arg3);
 947
 948        case KEYCTL_UNLINK:
 949                return keyctl_keyring_unlink((key_serial_t) arg2,
 950                                             (key_serial_t) arg3);
 951
 952        case KEYCTL_SEARCH:
 953                return keyctl_keyring_search((key_serial_t) arg2,
 954                                             (const char __user *) arg3,
 955                                             (const char __user *) arg4,
 956                                             (key_serial_t) arg5);
 957
 958        case KEYCTL_READ:
 959                return keyctl_read_key((key_serial_t) arg2,
 960                                       (char __user *) arg3,
 961                                       (size_t) arg4);
 962
 963        case KEYCTL_CHOWN:
 964                return keyctl_chown_key((key_serial_t) arg2,
 965                                        (uid_t) arg3,
 966                                        (gid_t) arg4);
 967
 968        case KEYCTL_SETPERM:
 969                return keyctl_setperm_key((key_serial_t) arg2,
 970                                          (key_perm_t) arg3);
 971
 972        case KEYCTL_INSTANTIATE:
 973                return keyctl_instantiate_key((key_serial_t) arg2,
 974                                              (const void __user *) arg3,
 975                                              (size_t) arg4,
 976                                              (key_serial_t) arg5);
 977
 978        case KEYCTL_NEGATE:
 979                return keyctl_negate_key((key_serial_t) arg2,
 980                                         (unsigned) arg3,
 981                                         (key_serial_t) arg4);
 982
 983        default:
 984                return -EOPNOTSUPP;
 985        }
 986
 987} /* end sys_keyctl() */
 988
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.