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.c213
1 files changed, 125 insertions, 88 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 2eb0e471cd40..9b0369c5a223 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -1,6 +1,6 @@
1/* process_keys.c: management of a process's keyrings 1/* process_keys.c: management of a process's keyrings
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -38,10 +38,9 @@ struct key root_user_keyring = {
38 .serial = 2, 38 .serial = 2,
39 .type = &key_type_keyring, 39 .type = &key_type_keyring,
40 .user = &root_key_user, 40 .user = &root_key_user,
41 .lock = RW_LOCK_UNLOCKED,
42 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), 41 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
43 .perm = KEY_USR_ALL, 42 .perm = KEY_USR_ALL,
44 .flags = KEY_FLAG_INSTANTIATED, 43 .flags = 1 << KEY_FLAG_INSTANTIATED,
45 .description = "_uid.0", 44 .description = "_uid.0",
46#ifdef KEY_DEBUGGING 45#ifdef KEY_DEBUGGING
47 .magic = KEY_DEBUG_MAGIC, 46 .magic = KEY_DEBUG_MAGIC,
@@ -54,10 +53,9 @@ struct key root_session_keyring = {
54 .serial = 1, 53 .serial = 1,
55 .type = &key_type_keyring, 54 .type = &key_type_keyring,
56 .user = &root_key_user, 55 .user = &root_key_user,
57 .lock = RW_LOCK_UNLOCKED,
58 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), 56 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
59 .perm = KEY_USR_ALL, 57 .perm = KEY_USR_ALL,
60 .flags = KEY_FLAG_INSTANTIATED, 58 .flags = 1 << KEY_FLAG_INSTANTIATED,
61 .description = "_uid_ses.0", 59 .description = "_uid_ses.0",
62#ifdef KEY_DEBUGGING 60#ifdef KEY_DEBUGGING
63 .magic = KEY_DEBUG_MAGIC, 61 .magic = KEY_DEBUG_MAGIC,
@@ -167,7 +165,7 @@ int install_thread_keyring(struct task_struct *tsk)
167/* 165/*
168 * make sure a process keyring is installed 166 * make sure a process keyring is installed
169 */ 167 */
170static int install_process_keyring(struct task_struct *tsk) 168int install_process_keyring(struct task_struct *tsk)
171{ 169{
172 unsigned long flags; 170 unsigned long flags;
173 struct key *keyring; 171 struct key *keyring;
@@ -183,7 +181,7 @@ static int install_process_keyring(struct task_struct *tsk)
183 goto error; 181 goto error;
184 } 182 }
185 183
186 /* attach or swap keyrings */ 184 /* attach keyring */
187 spin_lock_irqsave(&tsk->sighand->siglock, flags); 185 spin_lock_irqsave(&tsk->sighand->siglock, flags);
188 if (!tsk->signal->process_keyring) { 186 if (!tsk->signal->process_keyring) {
189 tsk->signal->process_keyring = keyring; 187 tsk->signal->process_keyring = keyring;
@@ -229,12 +227,14 @@ static int install_session_keyring(struct task_struct *tsk,
229 227
230 /* install the keyring */ 228 /* install the keyring */
231 spin_lock_irqsave(&tsk->sighand->siglock, flags); 229 spin_lock_irqsave(&tsk->sighand->siglock, flags);
232 old = tsk->signal->session_keyring; 230 old = rcu_dereference(tsk->signal->session_keyring);
233 tsk->signal->session_keyring = keyring; 231 rcu_assign_pointer(tsk->signal->session_keyring, keyring);
234 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 232 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
235 233
236 ret = 0; 234 ret = 0;
237 235
236 /* we're using RCU on the pointer */
237 synchronize_rcu();
238 key_put(old); 238 key_put(old);
239 error: 239 error:
240 return ret; 240 return ret;
@@ -247,8 +247,6 @@ static int install_session_keyring(struct task_struct *tsk,
247 */ 247 */
248int copy_thread_group_keys(struct task_struct *tsk) 248int copy_thread_group_keys(struct task_struct *tsk)
249{ 249{
250 unsigned long flags;
251
252 key_check(current->thread_group->session_keyring); 250 key_check(current->thread_group->session_keyring);
253 key_check(current->thread_group->process_keyring); 251 key_check(current->thread_group->process_keyring);
254 252
@@ -256,10 +254,10 @@ int copy_thread_group_keys(struct task_struct *tsk)
256 tsk->signal->process_keyring = NULL; 254 tsk->signal->process_keyring = NULL;
257 255
258 /* same session keyring */ 256 /* same session keyring */
259 spin_lock_irqsave(&current->sighand->siglock, flags); 257 rcu_read_lock();
260 tsk->signal->session_keyring = 258 tsk->signal->session_keyring =
261 key_get(current->signal->session_keyring); 259 key_get(rcu_dereference(current->signal->session_keyring));
262 spin_unlock_irqrestore(&current->sighand->siglock, flags); 260 rcu_read_unlock();
263 261
264 return 0; 262 return 0;
265 263
@@ -349,9 +347,7 @@ void key_fsuid_changed(struct task_struct *tsk)
349 /* update the ownership of the thread keyring */ 347 /* update the ownership of the thread keyring */
350 if (tsk->thread_keyring) { 348 if (tsk->thread_keyring) {
351 down_write(&tsk->thread_keyring->sem); 349 down_write(&tsk->thread_keyring->sem);
352 write_lock(&tsk->thread_keyring->lock);
353 tsk->thread_keyring->uid = tsk->fsuid; 350 tsk->thread_keyring->uid = tsk->fsuid;
354 write_unlock(&tsk->thread_keyring->lock);
355 up_write(&tsk->thread_keyring->sem); 351 up_write(&tsk->thread_keyring->sem);
356 } 352 }
357 353
@@ -366,9 +362,7 @@ void key_fsgid_changed(struct task_struct *tsk)
366 /* update the ownership of the thread keyring */ 362 /* update the ownership of the thread keyring */
367 if (tsk->thread_keyring) { 363 if (tsk->thread_keyring) {
368 down_write(&tsk->thread_keyring->sem); 364 down_write(&tsk->thread_keyring->sem);
369 write_lock(&tsk->thread_keyring->lock);
370 tsk->thread_keyring->gid = tsk->fsgid; 365 tsk->thread_keyring->gid = tsk->fsgid;
371 write_unlock(&tsk->thread_keyring->lock);
372 up_write(&tsk->thread_keyring->sem); 366 up_write(&tsk->thread_keyring->sem);
373 } 367 }
374 368
@@ -382,13 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk)
382 * - we return -EAGAIN if we didn't find any matching key 376 * - we return -EAGAIN if we didn't find any matching key
383 * - we return -ENOKEY if we found only negative matching keys 377 * - we return -ENOKEY if we found only negative matching keys
384 */ 378 */
385struct key *search_process_keyrings_aux(struct key_type *type, 379struct key *search_process_keyrings(struct key_type *type,
386 const void *description, 380 const void *description,
387 key_match_func_t match) 381 key_match_func_t match,
382 struct task_struct *context)
388{ 383{
389 struct task_struct *tsk = current; 384 struct request_key_auth *rka;
390 unsigned long flags; 385 struct key *key, *ret, *err, *instkey;
391 struct key *key, *ret, *err, *tmp;
392 386
393 /* 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
394 * 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;
@@ -402,9 +396,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
402 err = ERR_PTR(-EAGAIN); 396 err = ERR_PTR(-EAGAIN);
403 397
404 /* search the thread keyring first */ 398 /* search the thread keyring first */
405 if (tsk->thread_keyring) { 399 if (context->thread_keyring) {
406 key = keyring_search_aux(tsk->thread_keyring, type, 400 key = keyring_search_aux(context->thread_keyring,
407 description, match); 401 context, type, description, match);
408 if (!IS_ERR(key)) 402 if (!IS_ERR(key))
409 goto found; 403 goto found;
410 404
@@ -422,9 +416,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
422 } 416 }
423 417
424 /* search the process keyring second */ 418 /* search the process keyring second */
425 if (tsk->signal->process_keyring) { 419 if (context->signal->process_keyring) {
426 key = keyring_search_aux(tsk->signal->process_keyring, 420 key = keyring_search_aux(context->signal->process_keyring,
427 type, description, match); 421 context, type, description, match);
428 if (!IS_ERR(key)) 422 if (!IS_ERR(key))
429 goto found; 423 goto found;
430 424
@@ -441,52 +435,93 @@ struct key *search_process_keyrings_aux(struct key_type *type,
441 } 435 }
442 } 436 }
443 437
444 /* search the session keyring last */ 438 /* search the session keyring */
445 spin_lock_irqsave(&tsk->sighand->siglock, flags); 439 if (context->signal->session_keyring) {
440 rcu_read_lock();
441 key = keyring_search_aux(
442 rcu_dereference(context->signal->session_keyring),
443 context, type, description, match);
444 rcu_read_unlock();
446 445
447 tmp = tsk->signal->session_keyring; 446 if (!IS_ERR(key))
448 if (!tmp) 447 goto found;
449 tmp = tsk->user->session_keyring;
450 atomic_inc(&tmp->usage);
451 448
452 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 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;
453 477
454 key = keyring_search_aux(tmp, type, description, match); 478 key = search_process_keyrings(type, description, match,
455 key_put(tmp); 479 rka->context);
456 if (!IS_ERR(key)) 480 key_put(instkey);
457 goto found;
458 481
459 switch (PTR_ERR(key)) { 482 if (!IS_ERR(key))
460 case -EAGAIN: /* no key */ 483 goto found;
461 if (ret) 484
485 switch (PTR_ERR(key)) {
486 case -EAGAIN: /* no key */
487 if (ret)
488 break;
489 case -ENOKEY: /* negative key */
490 ret = key;
462 break; 491 break;
463 case -ENOKEY: /* negative key */ 492 default:
464 ret = key; 493 err = key;
465 break; 494 break;
466 default: 495 }
467 err = key; 496 }
468 break; 497 /* or search the user-session keyring */
498 else {
499 key = keyring_search_aux(context->user->session_keyring,
500 context, type, description, match);
501 if (!IS_ERR(key))
502 goto found;
503
504 switch (PTR_ERR(key)) {
505 case -EAGAIN: /* no key */
506 if (ret)
507 break;
508 case -ENOKEY: /* negative key */
509 ret = key;
510 break;
511 default:
512 err = key;
513 break;
514 }
469 } 515 }
470 516
517
518no_key:
471 /* 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 */
472 key = ret ? ret : err; 520 key = ret ? ret : err;
473 521
474 found: 522found:
475 return key; 523 return key;
476 524
477} /* end search_process_keyrings_aux() */
478
479/*****************************************************************************/
480/*
481 * search the process keyrings for the first matching key
482 * - we return -EAGAIN if we didn't find any matching key
483 * - we return -ENOKEY if we found only negative matching keys
484 */
485struct key *search_process_keyrings(struct key_type *type,
486 const char *description)
487{
488 return search_process_keyrings_aux(type, description, type->match);
489
490} /* end search_process_keyrings() */ 525} /* end search_process_keyrings() */
491 526
492/*****************************************************************************/ 527/*****************************************************************************/
@@ -495,72 +530,73 @@ struct key *search_process_keyrings(struct key_type *type,
495 * - don't create special keyrings unless so requested 530 * - don't create special keyrings unless so requested
496 * - partially constructed keys aren't found unless requested 531 * - partially constructed keys aren't found unless requested
497 */ 532 */
498struct 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,
499 key_perm_t perm) 534 int create, int partial, key_perm_t perm)
500{ 535{
501 struct task_struct *tsk = current;
502 unsigned long flags;
503 struct key *key; 536 struct key *key;
504 int ret; 537 int ret;
505 538
539 if (!context)
540 context = current;
541
506 key = ERR_PTR(-ENOKEY); 542 key = ERR_PTR(-ENOKEY);
507 543
508 switch (id) { 544 switch (id) {
509 case KEY_SPEC_THREAD_KEYRING: 545 case KEY_SPEC_THREAD_KEYRING:
510 if (!tsk->thread_keyring) { 546 if (!context->thread_keyring) {
511 if (!create) 547 if (!create)
512 goto error; 548 goto error;
513 549
514 ret = install_thread_keyring(tsk); 550 ret = install_thread_keyring(context);
515 if (ret < 0) { 551 if (ret < 0) {
516 key = ERR_PTR(ret); 552 key = ERR_PTR(ret);
517 goto error; 553 goto error;
518 } 554 }
519 } 555 }
520 556
521 key = tsk->thread_keyring; 557 key = context->thread_keyring;
522 atomic_inc(&key->usage); 558 atomic_inc(&key->usage);
523 break; 559 break;
524 560
525 case KEY_SPEC_PROCESS_KEYRING: 561 case KEY_SPEC_PROCESS_KEYRING:
526 if (!tsk->signal->process_keyring) { 562 if (!context->signal->process_keyring) {
527 if (!create) 563 if (!create)
528 goto error; 564 goto error;
529 565
530 ret = install_process_keyring(tsk); 566 ret = install_process_keyring(context);
531 if (ret < 0) { 567 if (ret < 0) {
532 key = ERR_PTR(ret); 568 key = ERR_PTR(ret);
533 goto error; 569 goto error;
534 } 570 }
535 } 571 }
536 572
537 key = tsk->signal->process_keyring; 573 key = context->signal->process_keyring;
538 atomic_inc(&key->usage); 574 atomic_inc(&key->usage);
539 break; 575 break;
540 576
541 case KEY_SPEC_SESSION_KEYRING: 577 case KEY_SPEC_SESSION_KEYRING:
542 if (!tsk->signal->session_keyring) { 578 if (!context->signal->session_keyring) {
543 /* always install a session keyring upon access if one 579 /* always install a session keyring upon access if one
544 * doesn't exist yet */ 580 * doesn't exist yet */
545 ret = install_session_keyring( 581 ret = install_session_keyring(
546 tsk, tsk->user->session_keyring); 582 context, context->user->session_keyring);
547 if (ret < 0) 583 if (ret < 0)
548 goto error; 584 goto error;
549 } 585 }
550 586
551 spin_lock_irqsave(&tsk->sighand->siglock, flags); 587 rcu_read_lock();
552 key = tsk->signal->session_keyring; 588 key = rcu_dereference(context->signal->session_keyring);
553 atomic_inc(&key->usage); 589 atomic_inc(&key->usage);
554 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 590 rcu_read_unlock();
555 break; 591 break;
556 592
557 case KEY_SPEC_USER_KEYRING: 593 case KEY_SPEC_USER_KEYRING:
558 key = tsk->user->uid_keyring; 594 key = context->user->uid_keyring;
559 atomic_inc(&key->usage); 595 atomic_inc(&key->usage);
560 break; 596 break;
561 597
562 case KEY_SPEC_USER_SESSION_KEYRING: 598 case KEY_SPEC_USER_SESSION_KEYRING:
563 key = tsk->user->session_keyring; 599 key = context->user->session_keyring;
564 atomic_inc(&key->usage); 600 atomic_inc(&key->usage);
565 break; 601 break;
566 602
@@ -580,7 +616,7 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
580 break; 616 break;
581 } 617 }
582 618
583 /* check the status and permissions */ 619 /* check the status */
584 if (perm) { 620 if (perm) {
585 ret = key_validate(key); 621 ret = key_validate(key);
586 if (ret < 0) 622 if (ret < 0)
@@ -588,11 +624,13 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
588 } 624 }
589 625
590 ret = -EIO; 626 ret = -EIO;
591 if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED)) 627 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
592 goto invalid_key; 628 goto invalid_key;
593 629
630 /* check the permissions */
594 ret = -EACCES; 631 ret = -EACCES;
595 if (!key_permission(key, perm)) 632
633 if (!key_task_permission(key, context, perm))
596 goto invalid_key; 634 goto invalid_key;
597 635
598 error: 636 error:
@@ -615,7 +653,6 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
615long join_session_keyring(const char *name) 653long join_session_keyring(const char *name)
616{ 654{
617 struct task_struct *tsk = current; 655 struct task_struct *tsk = current;
618 unsigned long flags;
619 struct key *keyring; 656 struct key *keyring;
620 long ret; 657 long ret;
621 658
@@ -625,9 +662,9 @@ long join_session_keyring(const char *name)
625 if (ret < 0) 662 if (ret < 0)
626 goto error; 663 goto error;
627 664
628 spin_lock_irqsave(&tsk->sighand->siglock, flags); 665 rcu_read_lock();
629 ret = tsk->signal->session_keyring->serial; 666 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
630 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 667 rcu_read_unlock();
631 goto error; 668 goto error;
632 } 669 }
633 670