at v2.6.21 765 lines 18 kB view raw
1/* process_keys.c: management of a process's keyrings 2 * 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#include <linux/module.h> 13#include <linux/init.h> 14#include <linux/sched.h> 15#include <linux/slab.h> 16#include <linux/keyctl.h> 17#include <linux/fs.h> 18#include <linux/err.h> 19#include <linux/mutex.h> 20#include <asm/uaccess.h> 21#include "internal.h" 22 23/* session keyring create vs join semaphore */ 24static DEFINE_MUTEX(key_session_mutex); 25 26/* the root user's tracking struct */ 27struct key_user root_key_user = { 28 .usage = ATOMIC_INIT(3), 29 .consq = LIST_HEAD_INIT(root_key_user.consq), 30 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), 31 .nkeys = ATOMIC_INIT(2), 32 .nikeys = ATOMIC_INIT(2), 33 .uid = 0, 34}; 35 36/* the root user's UID keyring */ 37struct key root_user_keyring = { 38 .usage = ATOMIC_INIT(1), 39 .serial = 2, 40 .type = &key_type_keyring, 41 .user = &root_key_user, 42 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), 43 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 44 .flags = 1 << KEY_FLAG_INSTANTIATED, 45 .description = "_uid.0", 46#ifdef KEY_DEBUGGING 47 .magic = KEY_DEBUG_MAGIC, 48#endif 49}; 50 51/* the root user's default session keyring */ 52struct key root_session_keyring = { 53 .usage = ATOMIC_INIT(1), 54 .serial = 1, 55 .type = &key_type_keyring, 56 .user = &root_key_user, 57 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), 58 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 59 .flags = 1 << KEY_FLAG_INSTANTIATED, 60 .description = "_uid_ses.0", 61#ifdef KEY_DEBUGGING 62 .magic = KEY_DEBUG_MAGIC, 63#endif 64}; 65 66/*****************************************************************************/ 67/* 68 * allocate the keyrings to be associated with a UID 69 */ 70int alloc_uid_keyring(struct user_struct *user, 71 struct task_struct *ctx) 72{ 73 struct key *uid_keyring, *session_keyring; 74 char buf[20]; 75 int ret; 76 77 /* concoct a default session keyring */ 78 sprintf(buf, "_uid_ses.%u", user->uid); 79 80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 81 KEY_ALLOC_IN_QUOTA, NULL); 82 if (IS_ERR(session_keyring)) { 83 ret = PTR_ERR(session_keyring); 84 goto error; 85 } 86 87 /* and a UID specific keyring, pointed to by the default session 88 * keyring */ 89 sprintf(buf, "_uid.%u", user->uid); 90 91 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 92 KEY_ALLOC_IN_QUOTA, session_keyring); 93 if (IS_ERR(uid_keyring)) { 94 key_put(session_keyring); 95 ret = PTR_ERR(uid_keyring); 96 goto error; 97 } 98 99 /* install the keyrings */ 100 user->uid_keyring = uid_keyring; 101 user->session_keyring = session_keyring; 102 ret = 0; 103 104error: 105 return ret; 106 107} /* end alloc_uid_keyring() */ 108 109/*****************************************************************************/ 110/* 111 * deal with the UID changing 112 */ 113void switch_uid_keyring(struct user_struct *new_user) 114{ 115#if 0 /* do nothing for now */ 116 struct key *old; 117 118 /* switch to the new user's session keyring if we were running under 119 * root's default session keyring */ 120 if (new_user->uid != 0 && 121 current->session_keyring == &root_session_keyring 122 ) { 123 atomic_inc(&new_user->session_keyring->usage); 124 125 task_lock(current); 126 old = current->session_keyring; 127 current->session_keyring = new_user->session_keyring; 128 task_unlock(current); 129 130 key_put(old); 131 } 132#endif 133 134} /* end switch_uid_keyring() */ 135 136/*****************************************************************************/ 137/* 138 * install a fresh thread keyring, discarding the old one 139 */ 140int install_thread_keyring(struct task_struct *tsk) 141{ 142 struct key *keyring, *old; 143 char buf[20]; 144 int ret; 145 146 sprintf(buf, "_tid.%u", tsk->pid); 147 148 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 149 KEY_ALLOC_QUOTA_OVERRUN, NULL); 150 if (IS_ERR(keyring)) { 151 ret = PTR_ERR(keyring); 152 goto error; 153 } 154 155 task_lock(tsk); 156 old = tsk->thread_keyring; 157 tsk->thread_keyring = keyring; 158 task_unlock(tsk); 159 160 ret = 0; 161 162 key_put(old); 163error: 164 return ret; 165 166} /* end install_thread_keyring() */ 167 168/*****************************************************************************/ 169/* 170 * make sure a process keyring is installed 171 */ 172int install_process_keyring(struct task_struct *tsk) 173{ 174 struct key *keyring; 175 char buf[20]; 176 int ret; 177 178 might_sleep(); 179 180 if (!tsk->signal->process_keyring) { 181 sprintf(buf, "_pid.%u", tsk->tgid); 182 183 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 184 KEY_ALLOC_QUOTA_OVERRUN, NULL); 185 if (IS_ERR(keyring)) { 186 ret = PTR_ERR(keyring); 187 goto error; 188 } 189 190 /* attach keyring */ 191 spin_lock_irq(&tsk->sighand->siglock); 192 if (!tsk->signal->process_keyring) { 193 tsk->signal->process_keyring = keyring; 194 keyring = NULL; 195 } 196 spin_unlock_irq(&tsk->sighand->siglock); 197 198 key_put(keyring); 199 } 200 201 ret = 0; 202error: 203 return ret; 204 205} /* end install_process_keyring() */ 206 207/*****************************************************************************/ 208/* 209 * install a session keyring, discarding the old one 210 * - if a keyring is not supplied, an empty one is invented 211 */ 212static int install_session_keyring(struct task_struct *tsk, 213 struct key *keyring) 214{ 215 unsigned long flags; 216 struct key *old; 217 char buf[20]; 218 219 might_sleep(); 220 221 /* create an empty session keyring */ 222 if (!keyring) { 223 sprintf(buf, "_ses.%u", tsk->tgid); 224 225 flags = KEY_ALLOC_QUOTA_OVERRUN; 226 if (tsk->signal->session_keyring) 227 flags = KEY_ALLOC_IN_QUOTA; 228 229 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 230 flags, NULL); 231 if (IS_ERR(keyring)) 232 return PTR_ERR(keyring); 233 } 234 else { 235 atomic_inc(&keyring->usage); 236 } 237 238 /* install the keyring */ 239 spin_lock_irq(&tsk->sighand->siglock); 240 old = tsk->signal->session_keyring; 241 rcu_assign_pointer(tsk->signal->session_keyring, keyring); 242 spin_unlock_irq(&tsk->sighand->siglock); 243 244 /* we're using RCU on the pointer, but there's no point synchronising 245 * on it if it didn't previously point to anything */ 246 if (old) { 247 synchronize_rcu(); 248 key_put(old); 249 } 250 251 return 0; 252 253} /* end install_session_keyring() */ 254 255/*****************************************************************************/ 256/* 257 * copy the keys in a thread group for fork without CLONE_THREAD 258 */ 259int copy_thread_group_keys(struct task_struct *tsk) 260{ 261 key_check(current->thread_group->session_keyring); 262 key_check(current->thread_group->process_keyring); 263 264 /* no process keyring yet */ 265 tsk->signal->process_keyring = NULL; 266 267 /* same session keyring */ 268 rcu_read_lock(); 269 tsk->signal->session_keyring = 270 key_get(rcu_dereference(current->signal->session_keyring)); 271 rcu_read_unlock(); 272 273 return 0; 274 275} /* end copy_thread_group_keys() */ 276 277/*****************************************************************************/ 278/* 279 * copy the keys for fork 280 */ 281int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 282{ 283 key_check(tsk->thread_keyring); 284 key_check(tsk->request_key_auth); 285 286 /* no thread keyring yet */ 287 tsk->thread_keyring = NULL; 288 289 /* copy the request_key() authorisation for this thread */ 290 key_get(tsk->request_key_auth); 291 292 return 0; 293 294} /* end copy_keys() */ 295 296/*****************************************************************************/ 297/* 298 * dispose of thread group keys upon thread group destruction 299 */ 300void exit_thread_group_keys(struct signal_struct *tg) 301{ 302 key_put(tg->session_keyring); 303 key_put(tg->process_keyring); 304 305} /* end exit_thread_group_keys() */ 306 307/*****************************************************************************/ 308/* 309 * dispose of per-thread keys upon thread exit 310 */ 311void exit_keys(struct task_struct *tsk) 312{ 313 key_put(tsk->thread_keyring); 314 key_put(tsk->request_key_auth); 315 316} /* end exit_keys() */ 317 318/*****************************************************************************/ 319/* 320 * deal with execve() 321 */ 322int exec_keys(struct task_struct *tsk) 323{ 324 struct key *old; 325 326 /* newly exec'd tasks don't get a thread keyring */ 327 task_lock(tsk); 328 old = tsk->thread_keyring; 329 tsk->thread_keyring = NULL; 330 task_unlock(tsk); 331 332 key_put(old); 333 334 /* discard the process keyring from a newly exec'd task */ 335 spin_lock_irq(&tsk->sighand->siglock); 336 old = tsk->signal->process_keyring; 337 tsk->signal->process_keyring = NULL; 338 spin_unlock_irq(&tsk->sighand->siglock); 339 340 key_put(old); 341 342 return 0; 343 344} /* end exec_keys() */ 345 346/*****************************************************************************/ 347/* 348 * deal with SUID programs 349 * - we might want to make this invent a new session keyring 350 */ 351int suid_keys(struct task_struct *tsk) 352{ 353 return 0; 354 355} /* end suid_keys() */ 356 357/*****************************************************************************/ 358/* 359 * the filesystem user ID changed 360 */ 361void key_fsuid_changed(struct task_struct *tsk) 362{ 363 /* update the ownership of the thread keyring */ 364 if (tsk->thread_keyring) { 365 down_write(&tsk->thread_keyring->sem); 366 tsk->thread_keyring->uid = tsk->fsuid; 367 up_write(&tsk->thread_keyring->sem); 368 } 369 370} /* end key_fsuid_changed() */ 371 372/*****************************************************************************/ 373/* 374 * the filesystem group ID changed 375 */ 376void key_fsgid_changed(struct task_struct *tsk) 377{ 378 /* update the ownership of the thread keyring */ 379 if (tsk->thread_keyring) { 380 down_write(&tsk->thread_keyring->sem); 381 tsk->thread_keyring->gid = tsk->fsgid; 382 up_write(&tsk->thread_keyring->sem); 383 } 384 385} /* end key_fsgid_changed() */ 386 387/*****************************************************************************/ 388/* 389 * search the process keyrings for the first matching key 390 * - we use the supplied match function to see if the description (or other 391 * feature of interest) matches 392 * - we return -EAGAIN if we didn't find any matching key 393 * - we return -ENOKEY if we found only negative matching keys 394 */ 395key_ref_t search_process_keyrings(struct key_type *type, 396 const void *description, 397 key_match_func_t match, 398 struct task_struct *context) 399{ 400 struct request_key_auth *rka; 401 key_ref_t key_ref, ret, err; 402 403 might_sleep(); 404 405 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 406 * searchable, but we failed to find a key or we found a negative key; 407 * otherwise we want to return a sample error (probably -EACCES) if 408 * none of the keyrings were searchable 409 * 410 * in terms of priority: success > -ENOKEY > -EAGAIN > other error 411 */ 412 key_ref = NULL; 413 ret = NULL; 414 err = ERR_PTR(-EAGAIN); 415 416 /* search the thread keyring first */ 417 if (context->thread_keyring) { 418 key_ref = keyring_search_aux( 419 make_key_ref(context->thread_keyring, 1), 420 context, type, description, match); 421 if (!IS_ERR(key_ref)) 422 goto found; 423 424 switch (PTR_ERR(key_ref)) { 425 case -EAGAIN: /* no key */ 426 if (ret) 427 break; 428 case -ENOKEY: /* negative key */ 429 ret = key_ref; 430 break; 431 default: 432 err = key_ref; 433 break; 434 } 435 } 436 437 /* search the process keyring second */ 438 if (context->signal->process_keyring) { 439 key_ref = keyring_search_aux( 440 make_key_ref(context->signal->process_keyring, 1), 441 context, type, description, match); 442 if (!IS_ERR(key_ref)) 443 goto found; 444 445 switch (PTR_ERR(key_ref)) { 446 case -EAGAIN: /* no key */ 447 if (ret) 448 break; 449 case -ENOKEY: /* negative key */ 450 ret = key_ref; 451 break; 452 default: 453 err = key_ref; 454 break; 455 } 456 } 457 458 /* search the session keyring */ 459 if (context->signal->session_keyring) { 460 rcu_read_lock(); 461 key_ref = keyring_search_aux( 462 make_key_ref(rcu_dereference( 463 context->signal->session_keyring), 464 1), 465 context, type, description, match); 466 rcu_read_unlock(); 467 468 if (!IS_ERR(key_ref)) 469 goto found; 470 471 switch (PTR_ERR(key_ref)) { 472 case -EAGAIN: /* no key */ 473 if (ret) 474 break; 475 case -ENOKEY: /* negative key */ 476 ret = key_ref; 477 break; 478 default: 479 err = key_ref; 480 break; 481 } 482 } 483 /* or search the user-session keyring */ 484 else { 485 key_ref = keyring_search_aux( 486 make_key_ref(context->user->session_keyring, 1), 487 context, type, description, match); 488 if (!IS_ERR(key_ref)) 489 goto found; 490 491 switch (PTR_ERR(key_ref)) { 492 case -EAGAIN: /* no key */ 493 if (ret) 494 break; 495 case -ENOKEY: /* negative key */ 496 ret = key_ref; 497 break; 498 default: 499 err = key_ref; 500 break; 501 } 502 } 503 504 /* if this process has an instantiation authorisation key, then we also 505 * search the keyrings of the process mentioned there 506 * - we don't permit access to request_key auth keys via this method 507 */ 508 if (context->request_key_auth && 509 context == current && 510 type != &key_type_request_key_auth 511 ) { 512 /* defend against the auth key being revoked */ 513 down_read(&context->request_key_auth->sem); 514 515 if (key_validate(context->request_key_auth) == 0) { 516 rka = context->request_key_auth->payload.data; 517 518 key_ref = search_process_keyrings(type, description, 519 match, rka->context); 520 521 up_read(&context->request_key_auth->sem); 522 523 if (!IS_ERR(key_ref)) 524 goto found; 525 526 switch (PTR_ERR(key_ref)) { 527 case -EAGAIN: /* no key */ 528 if (ret) 529 break; 530 case -ENOKEY: /* negative key */ 531 ret = key_ref; 532 break; 533 default: 534 err = key_ref; 535 break; 536 } 537 } else { 538 up_read(&context->request_key_auth->sem); 539 } 540 } 541 542 /* no key - decide on the error we're going to go for */ 543 key_ref = ret ? ret : err; 544 545found: 546 return key_ref; 547 548} /* end search_process_keyrings() */ 549 550/*****************************************************************************/ 551/* 552 * see if the key we're looking at is the target key 553 */ 554static int lookup_user_key_possessed(const struct key *key, const void *target) 555{ 556 return key == target; 557 558} /* end lookup_user_key_possessed() */ 559 560/*****************************************************************************/ 561/* 562 * lookup a key given a key ID from userspace with a given permissions mask 563 * - don't create special keyrings unless so requested 564 * - partially constructed keys aren't found unless requested 565 */ 566key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, 567 int create, int partial, key_perm_t perm) 568{ 569 key_ref_t key_ref, skey_ref; 570 struct key *key; 571 int ret; 572 573 if (!context) 574 context = current; 575 576 key_ref = ERR_PTR(-ENOKEY); 577 578 switch (id) { 579 case KEY_SPEC_THREAD_KEYRING: 580 if (!context->thread_keyring) { 581 if (!create) 582 goto error; 583 584 ret = install_thread_keyring(context); 585 if (ret < 0) { 586 key = ERR_PTR(ret); 587 goto error; 588 } 589 } 590 591 key = context->thread_keyring; 592 atomic_inc(&key->usage); 593 key_ref = make_key_ref(key, 1); 594 break; 595 596 case KEY_SPEC_PROCESS_KEYRING: 597 if (!context->signal->process_keyring) { 598 if (!create) 599 goto error; 600 601 ret = install_process_keyring(context); 602 if (ret < 0) { 603 key = ERR_PTR(ret); 604 goto error; 605 } 606 } 607 608 key = context->signal->process_keyring; 609 atomic_inc(&key->usage); 610 key_ref = make_key_ref(key, 1); 611 break; 612 613 case KEY_SPEC_SESSION_KEYRING: 614 if (!context->signal->session_keyring) { 615 /* always install a session keyring upon access if one 616 * doesn't exist yet */ 617 ret = install_session_keyring( 618 context, context->user->session_keyring); 619 if (ret < 0) 620 goto error; 621 } 622 623 rcu_read_lock(); 624 key = rcu_dereference(context->signal->session_keyring); 625 atomic_inc(&key->usage); 626 rcu_read_unlock(); 627 key_ref = make_key_ref(key, 1); 628 break; 629 630 case KEY_SPEC_USER_KEYRING: 631 key = context->user->uid_keyring; 632 atomic_inc(&key->usage); 633 key_ref = make_key_ref(key, 1); 634 break; 635 636 case KEY_SPEC_USER_SESSION_KEYRING: 637 key = context->user->session_keyring; 638 atomic_inc(&key->usage); 639 key_ref = make_key_ref(key, 1); 640 break; 641 642 case KEY_SPEC_GROUP_KEYRING: 643 /* group keyrings are not yet supported */ 644 key = ERR_PTR(-EINVAL); 645 goto error; 646 647 case KEY_SPEC_REQKEY_AUTH_KEY: 648 key = context->request_key_auth; 649 if (!key) 650 goto error; 651 652 atomic_inc(&key->usage); 653 key_ref = make_key_ref(key, 1); 654 break; 655 656 default: 657 key_ref = ERR_PTR(-EINVAL); 658 if (id < 1) 659 goto error; 660 661 key = key_lookup(id); 662 if (IS_ERR(key)) { 663 key_ref = ERR_PTR(PTR_ERR(key)); 664 goto error; 665 } 666 667 key_ref = make_key_ref(key, 0); 668 669 /* check to see if we possess the key */ 670 skey_ref = search_process_keyrings(key->type, key, 671 lookup_user_key_possessed, 672 current); 673 674 if (!IS_ERR(skey_ref)) { 675 key_put(key); 676 key_ref = skey_ref; 677 } 678 679 break; 680 } 681 682 /* check the status */ 683 if (perm) { 684 ret = key_validate(key); 685 if (ret < 0) 686 goto invalid_key; 687 } 688 689 ret = -EIO; 690 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 691 goto invalid_key; 692 693 /* check the permissions */ 694 ret = key_task_permission(key_ref, context, perm); 695 if (ret < 0) 696 goto invalid_key; 697 698error: 699 return key_ref; 700 701invalid_key: 702 key_ref_put(key_ref); 703 key_ref = ERR_PTR(ret); 704 goto error; 705 706} /* end lookup_user_key() */ 707 708/*****************************************************************************/ 709/* 710 * join the named keyring as the session keyring if possible, or attempt to 711 * create a new one of that name if not 712 * - if the name is NULL, an empty anonymous keyring is installed instead 713 * - named session keyring joining is done with a semaphore held 714 */ 715long join_session_keyring(const char *name) 716{ 717 struct task_struct *tsk = current; 718 struct key *keyring; 719 long ret; 720 721 /* if no name is provided, install an anonymous keyring */ 722 if (!name) { 723 ret = install_session_keyring(tsk, NULL); 724 if (ret < 0) 725 goto error; 726 727 rcu_read_lock(); 728 ret = rcu_dereference(tsk->signal->session_keyring)->serial; 729 rcu_read_unlock(); 730 goto error; 731 } 732 733 /* allow the user to join or create a named keyring */ 734 mutex_lock(&key_session_mutex); 735 736 /* look for an existing keyring of this name */ 737 keyring = find_keyring_by_name(name, 0); 738 if (PTR_ERR(keyring) == -ENOKEY) { 739 /* not found - try and create a new one */ 740 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 741 KEY_ALLOC_IN_QUOTA, NULL); 742 if (IS_ERR(keyring)) { 743 ret = PTR_ERR(keyring); 744 goto error2; 745 } 746 } 747 else if (IS_ERR(keyring)) { 748 ret = PTR_ERR(keyring); 749 goto error2; 750 } 751 752 /* we've got a keyring - now to install it */ 753 ret = install_session_keyring(tsk, keyring); 754 if (ret < 0) 755 goto error2; 756 757 ret = keyring->serial; 758 key_put(keyring); 759 760error2: 761 mutex_unlock(&key_session_mutex); 762error: 763 return ret; 764 765} /* end join_session_keyring() */