aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/process_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r--security/keys/process_keys.c179
1 files changed, 111 insertions, 68 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 972e30172687..34db087bbcc7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -165,7 +165,7 @@ int install_thread_keyring(struct task_struct *tsk)
165/* 165/*
166 * make sure a process keyring is installed 166 * make sure a process keyring is installed
167 */ 167 */
168static int install_process_keyring(struct task_struct *tsk) 168int install_process_keyring(struct task_struct *tsk)
169{ 169{
170 unsigned long flags; 170 unsigned long flags;
171 struct key *keyring; 171 struct key *keyring;
@@ -376,12 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk)
376 * - we return -EAGAIN if we didn't find any matching key 376 * - we return -EAGAIN if we didn't find any matching key
377 * - we return -ENOKEY if we found only negative matching keys 377 * - we return -ENOKEY if we found only negative matching keys
378 */ 378 */
379struct key *search_process_keyrings_aux(struct key_type *type, 379struct key *search_process_keyrings(struct key_type *type,
380 const void *description, 380 const void *description,
381 key_match_func_t match) 381 key_match_func_t match,
382 struct task_struct *context)
382{ 383{
383 struct task_struct *tsk = current; 384 struct request_key_auth *rka;
384 struct key *key, *ret, *err; 385 struct key *key, *ret, *err, *instkey;
385 386
386 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
387 * searchable, but we failed to find a key or we found a negative key; 388 * searchable, but we failed to find a key or we found a negative key;
@@ -395,9 +396,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
395 err = ERR_PTR(-EAGAIN); 396 err = ERR_PTR(-EAGAIN);
396 397
397 /* search the thread keyring first */ 398 /* search the thread keyring first */
398 if (tsk->thread_keyring) { 399 if (context->thread_keyring) {
399 key = keyring_search_aux(tsk->thread_keyring, type, 400 key = keyring_search_aux(context->thread_keyring,
400 description, match); 401 context, type, description, match);
401 if (!IS_ERR(key)) 402 if (!IS_ERR(key))
402 goto found; 403 goto found;
403 404
@@ -415,9 +416,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
415 } 416 }
416 417
417 /* search the process keyring second */ 418 /* search the process keyring second */
418 if (tsk->signal->process_keyring) { 419 if (context->signal->process_keyring) {
419 key = keyring_search_aux(tsk->signal->process_keyring, 420 key = keyring_search_aux(context->signal->process_keyring,
420 type, description, match); 421 context, type, description, match);
421 if (!IS_ERR(key)) 422 if (!IS_ERR(key))
422 goto found; 423 goto found;
423 424
@@ -434,53 +435,93 @@ struct key *search_process_keyrings_aux(struct key_type *type,
434 } 435 }
435 } 436 }
436 437
437 /* search the session keyring last */ 438 /* search the session keyring */
438 if (tsk->signal->session_keyring) { 439 if (context->signal->session_keyring) {
439 rcu_read_lock(); 440 rcu_read_lock();
440 key = keyring_search_aux( 441 key = keyring_search_aux(
441 rcu_dereference(tsk->signal->session_keyring), 442 rcu_dereference(context->signal->session_keyring),
442 type, description, match); 443 context, type, description, match);
443 rcu_read_unlock(); 444 rcu_read_unlock();
445
446 if (!IS_ERR(key))
447 goto found;
448
449 switch (PTR_ERR(key)) {
450 case -EAGAIN: /* no key */
451 if (ret)
452 break;
453 case -ENOKEY: /* negative key */
454 ret = key;
455 break;
456 default:
457 err = key;
458 break;
459 }
460
461 /* if this process has a session keyring and that has an
462 * instantiation authorisation key in the bottom level, then we
463 * also search the keyrings of the process mentioned there */
464 if (context != current)
465 goto no_key;
466
467 rcu_read_lock();
468 instkey = __keyring_search_one(
469 rcu_dereference(context->signal->session_keyring),
470 &key_type_request_key_auth, NULL, 0);
471 rcu_read_unlock();
472
473 if (IS_ERR(instkey))
474 goto no_key;
475
476 rka = instkey->payload.data;
477
478 key = search_process_keyrings(type, description, match,
479 rka->context);
480 key_put(instkey);
481
482 if (!IS_ERR(key))
483 goto found;
484
485 switch (PTR_ERR(key)) {
486 case -EAGAIN: /* no key */
487 if (ret)
488 break;
489 case -ENOKEY: /* negative key */
490 ret = key;
491 break;
492 default:
493 err = key;
494 break;
495 }
444 } 496 }
497 /* or search the user-session keyring */
445 else { 498 else {
446 key = keyring_search_aux(tsk->user->session_keyring, 499 key = keyring_search_aux(context->user->session_keyring,
447 type, description, match); 500 context, type, description, match);
448 } 501 if (!IS_ERR(key))
449 502 goto found;
450 if (!IS_ERR(key))
451 goto found;
452 503
453 switch (PTR_ERR(key)) { 504 switch (PTR_ERR(key)) {
454 case -EAGAIN: /* no key */ 505 case -EAGAIN: /* no key */
455 if (ret) 506 if (ret)
507 break;
508 case -ENOKEY: /* negative key */
509 ret = key;
456 break; 510 break;
457 case -ENOKEY: /* negative key */ 511 default:
458 ret = key; 512 err = key;
459 break; 513 break;
460 default: 514 }
461 err = key;
462 break;
463 } 515 }
464 516
517
518no_key:
465 /* no key - decide on the error we're going to go for */ 519 /* no key - decide on the error we're going to go for */
466 key = ret ? ret : err; 520 key = ret ? ret : err;
467 521
468 found: 522found:
469 return key; 523 return key;
470 524
471} /* end search_process_keyrings_aux() */
472
473/*****************************************************************************/
474/*
475 * search the process keyrings for the first matching key
476 * - we return -EAGAIN if we didn't find any matching key
477 * - we return -ENOKEY if we found only negative matching keys
478 */
479struct key *search_process_keyrings(struct key_type *type,
480 const char *description)
481{
482 return search_process_keyrings_aux(type, description, type->match);
483
484} /* end search_process_keyrings() */ 525} /* end search_process_keyrings() */
485 526
486/*****************************************************************************/ 527/*****************************************************************************/
@@ -489,72 +530,73 @@ struct key *search_process_keyrings(struct key_type *type,
489 * - don't create special keyrings unless so requested 530 * - don't create special keyrings unless so requested
490 * - partially constructed keys aren't found unless requested 531 * - partially constructed keys aren't found unless requested
491 */ 532 */
492struct key *lookup_user_key(key_serial_t id, int create, int partial, 533struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
493 key_perm_t perm) 534 int create, int partial, key_perm_t perm)
494{ 535{
495 struct task_struct *tsk = current;
496 unsigned long flags;
497 struct key *key; 536 struct key *key;
498 int ret; 537 int ret;
499 538
539 if (!context)
540 context = current;
541
500 key = ERR_PTR(-ENOKEY); 542 key = ERR_PTR(-ENOKEY);
501 543
502 switch (id) { 544 switch (id) {
503 case KEY_SPEC_THREAD_KEYRING: 545 case KEY_SPEC_THREAD_KEYRING:
504 if (!tsk->thread_keyring) { 546 if (!context->thread_keyring) {
505 if (!create) 547 if (!create)
506 goto error; 548 goto error;
507 549
508 ret = install_thread_keyring(tsk); 550 ret = install_thread_keyring(context);
509 if (ret < 0) { 551 if (ret < 0) {
510 key = ERR_PTR(ret); 552 key = ERR_PTR(ret);
511 goto error; 553 goto error;
512 } 554 }
513 } 555 }
514 556
515 key = tsk->thread_keyring; 557 key = context->thread_keyring;
516 atomic_inc(&key->usage); 558 atomic_inc(&key->usage);
517 break; 559 break;
518 560
519 case KEY_SPEC_PROCESS_KEYRING: 561 case KEY_SPEC_PROCESS_KEYRING:
520 if (!tsk->signal->process_keyring) { 562 if (!context->signal->process_keyring) {
521 if (!create) 563 if (!create)
522 goto error; 564 goto error;
523 565
524 ret = install_process_keyring(tsk); 566 ret = install_process_keyring(context);
525 if (ret < 0) { 567 if (ret < 0) {
526 key = ERR_PTR(ret); 568 key = ERR_PTR(ret);
527 goto error; 569 goto error;
528 } 570 }
529 } 571 }
530 572
531 key = tsk->signal->process_keyring; 573 key = context->signal->process_keyring;
532 atomic_inc(&key->usage); 574 atomic_inc(&key->usage);
533 break; 575 break;
534 576
535 case KEY_SPEC_SESSION_KEYRING: 577 case KEY_SPEC_SESSION_KEYRING:
536 if (!tsk->signal->session_keyring) { 578 if (!context->signal->session_keyring) {
537 /* always install a session keyring upon access if one 579 /* always install a session keyring upon access if one
538 * doesn't exist yet */ 580 * doesn't exist yet */
539 ret = install_session_keyring( 581 ret = install_session_keyring(
540 tsk, tsk->user->session_keyring); 582 context, context->user->session_keyring);
541 if (ret < 0) 583 if (ret < 0)
542 goto error; 584 goto error;
543 } 585 }
544 586
545 spin_lock_irqsave(&tsk->sighand->siglock, flags); 587 rcu_read_lock();
546 key = tsk->signal->session_keyring; 588 key = rcu_dereference(context->signal->session_keyring);
547 atomic_inc(&key->usage); 589 atomic_inc(&key->usage);
548 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 590 rcu_read_unlock();
549 break; 591 break;
550 592
551 case KEY_SPEC_USER_KEYRING: 593 case KEY_SPEC_USER_KEYRING:
552 key = tsk->user->uid_keyring; 594 key = context->user->uid_keyring;
553 atomic_inc(&key->usage); 595 atomic_inc(&key->usage);
554 break; 596 break;
555 597
556 case KEY_SPEC_USER_SESSION_KEYRING: 598 case KEY_SPEC_USER_SESSION_KEYRING:
557 key = tsk->user->session_keyring; 599 key = context->user->session_keyring;
558 atomic_inc(&key->usage); 600 atomic_inc(&key->usage);
559 break; 601 break;
560 602
@@ -574,7 +616,7 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
574 break; 616 break;
575 } 617 }
576 618
577 /* check the status and permissions */ 619 /* check the status */
578 if (perm) { 620 if (perm) {
579 ret = key_validate(key); 621 ret = key_validate(key);
580 if (ret < 0) 622 if (ret < 0)
@@ -585,8 +627,10 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
585 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 627 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
586 goto invalid_key; 628 goto invalid_key;
587 629
630 /* check the permissions */
588 ret = -EACCES; 631 ret = -EACCES;
589 if (!key_permission(key, perm)) 632
633 if (!key_task_permission(key, context, perm))
590 goto invalid_key; 634 goto invalid_key;
591 635
592 error: 636 error:
@@ -609,7 +653,6 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
609long join_session_keyring(const char *name) 653long join_session_keyring(const char *name)
610{ 654{
611 struct task_struct *tsk = current; 655 struct task_struct *tsk = current;
612 unsigned long flags;
613 struct key *keyring; 656 struct key *keyring;
614 long ret; 657 long ret;
615 658
@@ -619,9 +662,9 @@ long join_session_keyring(const char *name)
619 if (ret < 0) 662 if (ret < 0)
620 goto error; 663 goto error;
621 664
622 spin_lock_irqsave(&tsk->sighand->siglock, flags); 665 rcu_read_lock();
623 ret = tsk->signal->session_keyring->serial; 666 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
624 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 667 rcu_read_unlock();
625 goto error; 668 goto error;
626 } 669 }
627 670