aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-09-02 04:13:45 -0400
committerJames Morris <jmorris@namei.org>2009-09-02 07:29:04 -0400
commit5593122eec26b061cc0b6fbff32118f1aadf4a27 (patch)
treef148b182ada54b722962607567bd5b1ace06640a
parente0e817392b9acf2c98d3be80c233dddb1b52003d (diff)
KEYS: Deal with dead-type keys appropriately [try #6]
Allow keys for which the key type has been removed to be unlinked. Currently dead-type keys can only be disposed of by completely clearing the keyrings that point to them. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/keys/internal.h5
-rw-r--r--security/keys/key.c6
-rw-r--r--security/keys/keyctl.c50
-rw-r--r--security/keys/process_keys.c18
4 files changed, 48 insertions, 31 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 9fb679c66b8a..a7252e7b2e05 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -124,8 +124,11 @@ extern struct key *request_key_and_link(struct key_type *type,
124 struct key *dest_keyring, 124 struct key *dest_keyring,
125 unsigned long flags); 125 unsigned long flags);
126 126
127extern key_ref_t lookup_user_key(key_serial_t id, int create, int partial, 127extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
128 key_perm_t perm); 128 key_perm_t perm);
129#define KEY_LOOKUP_CREATE 0x01
130#define KEY_LOOKUP_PARTIAL 0x02
131#define KEY_LOOKUP_FOR_UNLINK 0x04
129 132
130extern long join_session_keyring(const char *name); 133extern long join_session_keyring(const char *name);
131 134
diff --git a/security/keys/key.c b/security/keys/key.c
index 4a1297d1ada4..3762d5b1ce64 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -642,10 +642,8 @@ struct key *key_lookup(key_serial_t id)
642 goto error; 642 goto error;
643 643
644 found: 644 found:
645 /* pretend it doesn't exist if it's dead */ 645 /* pretend it doesn't exist if it is awaiting deletion */
646 if (atomic_read(&key->usage) == 0 || 646 if (atomic_read(&key->usage) == 0)
647 test_bit(KEY_FLAG_DEAD, &key->flags) ||
648 key->type == &key_type_dead)
649 goto not_found; 647 goto not_found;
650 648
651 /* this races with key_put(), but that doesn't matter since key_put() 649 /* this races with key_put(), but that doesn't matter since key_put()
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 7f09fb897d2b..b85ace218395 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -103,7 +103,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
103 } 103 }
104 104
105 /* find the target keyring (which must be writable) */ 105 /* find the target keyring (which must be writable) */
106 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); 106 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
107 if (IS_ERR(keyring_ref)) { 107 if (IS_ERR(keyring_ref)) {
108 ret = PTR_ERR(keyring_ref); 108 ret = PTR_ERR(keyring_ref);
109 goto error3; 109 goto error3;
@@ -185,7 +185,8 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
185 /* get the destination keyring if specified */ 185 /* get the destination keyring if specified */
186 dest_ref = NULL; 186 dest_ref = NULL;
187 if (destringid) { 187 if (destringid) {
188 dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); 188 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
189 KEY_WRITE);
189 if (IS_ERR(dest_ref)) { 190 if (IS_ERR(dest_ref)) {
190 ret = PTR_ERR(dest_ref); 191 ret = PTR_ERR(dest_ref);
191 goto error3; 192 goto error3;
@@ -233,9 +234,11 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
233long keyctl_get_keyring_ID(key_serial_t id, int create) 234long keyctl_get_keyring_ID(key_serial_t id, int create)
234{ 235{
235 key_ref_t key_ref; 236 key_ref_t key_ref;
237 unsigned long lflags;
236 long ret; 238 long ret;
237 239
238 key_ref = lookup_user_key(id, create, 0, KEY_SEARCH); 240 lflags = create ? KEY_LOOKUP_CREATE : 0;
241 key_ref = lookup_user_key(id, lflags, KEY_SEARCH);
239 if (IS_ERR(key_ref)) { 242 if (IS_ERR(key_ref)) {
240 ret = PTR_ERR(key_ref); 243 ret = PTR_ERR(key_ref);
241 goto error; 244 goto error;
@@ -309,7 +312,7 @@ long keyctl_update_key(key_serial_t id,
309 } 312 }
310 313
311 /* find the target key (which must be writable) */ 314 /* find the target key (which must be writable) */
312 key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); 315 key_ref = lookup_user_key(id, 0, KEY_WRITE);
313 if (IS_ERR(key_ref)) { 316 if (IS_ERR(key_ref)) {
314 ret = PTR_ERR(key_ref); 317 ret = PTR_ERR(key_ref);
315 goto error2; 318 goto error2;
@@ -337,7 +340,7 @@ long keyctl_revoke_key(key_serial_t id)
337 key_ref_t key_ref; 340 key_ref_t key_ref;
338 long ret; 341 long ret;
339 342
340 key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); 343 key_ref = lookup_user_key(id, 0, KEY_WRITE);
341 if (IS_ERR(key_ref)) { 344 if (IS_ERR(key_ref)) {
342 ret = PTR_ERR(key_ref); 345 ret = PTR_ERR(key_ref);
343 goto error; 346 goto error;
@@ -363,7 +366,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
363 key_ref_t keyring_ref; 366 key_ref_t keyring_ref;
364 long ret; 367 long ret;
365 368
366 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); 369 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
367 if (IS_ERR(keyring_ref)) { 370 if (IS_ERR(keyring_ref)) {
368 ret = PTR_ERR(keyring_ref); 371 ret = PTR_ERR(keyring_ref);
369 goto error; 372 goto error;
@@ -389,13 +392,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
389 key_ref_t keyring_ref, key_ref; 392 key_ref_t keyring_ref, key_ref;
390 long ret; 393 long ret;
391 394
392 keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); 395 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
393 if (IS_ERR(keyring_ref)) { 396 if (IS_ERR(keyring_ref)) {
394 ret = PTR_ERR(keyring_ref); 397 ret = PTR_ERR(keyring_ref);
395 goto error; 398 goto error;
396 } 399 }
397 400
398 key_ref = lookup_user_key(id, 1, 0, KEY_LINK); 401 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_LINK);
399 if (IS_ERR(key_ref)) { 402 if (IS_ERR(key_ref)) {
400 ret = PTR_ERR(key_ref); 403 ret = PTR_ERR(key_ref);
401 goto error2; 404 goto error2;
@@ -423,13 +426,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
423 key_ref_t keyring_ref, key_ref; 426 key_ref_t keyring_ref, key_ref;
424 long ret; 427 long ret;
425 428
426 keyring_ref = lookup_user_key(ringid, 0, 0, KEY_WRITE); 429 keyring_ref = lookup_user_key(ringid, 0, KEY_WRITE);
427 if (IS_ERR(keyring_ref)) { 430 if (IS_ERR(keyring_ref)) {
428 ret = PTR_ERR(keyring_ref); 431 ret = PTR_ERR(keyring_ref);
429 goto error; 432 goto error;
430 } 433 }
431 434
432 key_ref = lookup_user_key(id, 0, 0, 0); 435 key_ref = lookup_user_key(id, KEY_LOOKUP_FOR_UNLINK, 0);
433 if (IS_ERR(key_ref)) { 436 if (IS_ERR(key_ref)) {
434 ret = PTR_ERR(key_ref); 437 ret = PTR_ERR(key_ref);
435 goto error2; 438 goto error2;
@@ -465,7 +468,7 @@ long keyctl_describe_key(key_serial_t keyid,
465 char *tmpbuf; 468 char *tmpbuf;
466 long ret; 469 long ret;
467 470
468 key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); 471 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW);
469 if (IS_ERR(key_ref)) { 472 if (IS_ERR(key_ref)) {
470 /* viewing a key under construction is permitted if we have the 473 /* viewing a key under construction is permitted if we have the
471 * authorisation token handy */ 474 * authorisation token handy */
@@ -474,7 +477,8 @@ long keyctl_describe_key(key_serial_t keyid,
474 if (!IS_ERR(instkey)) { 477 if (!IS_ERR(instkey)) {
475 key_put(instkey); 478 key_put(instkey);
476 key_ref = lookup_user_key(keyid, 479 key_ref = lookup_user_key(keyid,
477 0, 1, 0); 480 KEY_LOOKUP_PARTIAL,
481 0);
478 if (!IS_ERR(key_ref)) 482 if (!IS_ERR(key_ref))
479 goto okay; 483 goto okay;
480 } 484 }
@@ -558,7 +562,7 @@ long keyctl_keyring_search(key_serial_t ringid,
558 } 562 }
559 563
560 /* get the keyring at which to begin the search */ 564 /* get the keyring at which to begin the search */
561 keyring_ref = lookup_user_key(ringid, 0, 0, KEY_SEARCH); 565 keyring_ref = lookup_user_key(ringid, 0, KEY_SEARCH);
562 if (IS_ERR(keyring_ref)) { 566 if (IS_ERR(keyring_ref)) {
563 ret = PTR_ERR(keyring_ref); 567 ret = PTR_ERR(keyring_ref);
564 goto error2; 568 goto error2;
@@ -567,7 +571,8 @@ long keyctl_keyring_search(key_serial_t ringid,
567 /* get the destination keyring if specified */ 571 /* get the destination keyring if specified */
568 dest_ref = NULL; 572 dest_ref = NULL;
569 if (destringid) { 573 if (destringid) {
570 dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); 574 dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE,
575 KEY_WRITE);
571 if (IS_ERR(dest_ref)) { 576 if (IS_ERR(dest_ref)) {
572 ret = PTR_ERR(dest_ref); 577 ret = PTR_ERR(dest_ref);
573 goto error3; 578 goto error3;
@@ -637,7 +642,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
637 long ret; 642 long ret;
638 643
639 /* find the key first */ 644 /* find the key first */
640 key_ref = lookup_user_key(keyid, 0, 0, 0); 645 key_ref = lookup_user_key(keyid, 0, 0);
641 if (IS_ERR(key_ref)) { 646 if (IS_ERR(key_ref)) {
642 ret = -ENOKEY; 647 ret = -ENOKEY;
643 goto error; 648 goto error;
@@ -700,7 +705,8 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
700 if (uid == (uid_t) -1 && gid == (gid_t) -1) 705 if (uid == (uid_t) -1 && gid == (gid_t) -1)
701 goto error; 706 goto error;
702 707
703 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); 708 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
709 KEY_SETATTR);
704 if (IS_ERR(key_ref)) { 710 if (IS_ERR(key_ref)) {
705 ret = PTR_ERR(key_ref); 711 ret = PTR_ERR(key_ref);
706 goto error; 712 goto error;
@@ -805,7 +811,8 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
805 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 811 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
806 goto error; 812 goto error;
807 813
808 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); 814 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
815 KEY_SETATTR);
809 if (IS_ERR(key_ref)) { 816 if (IS_ERR(key_ref)) {
810 ret = PTR_ERR(key_ref); 817 ret = PTR_ERR(key_ref);
811 goto error; 818 goto error;
@@ -847,7 +854,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
847 854
848 /* if a specific keyring is nominated by ID, then use that */ 855 /* if a specific keyring is nominated by ID, then use that */
849 if (ringid > 0) { 856 if (ringid > 0) {
850 dkref = lookup_user_key(ringid, 1, 0, KEY_WRITE); 857 dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
851 if (IS_ERR(dkref)) 858 if (IS_ERR(dkref))
852 return PTR_ERR(dkref); 859 return PTR_ERR(dkref);
853 *_dest_keyring = key_ref_to_ptr(dkref); 860 *_dest_keyring = key_ref_to_ptr(dkref);
@@ -1083,7 +1090,8 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
1083 time_t expiry; 1090 time_t expiry;
1084 long ret; 1091 long ret;
1085 1092
1086 key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); 1093 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
1094 KEY_SETATTR);
1087 if (IS_ERR(key_ref)) { 1095 if (IS_ERR(key_ref)) {
1088 ret = PTR_ERR(key_ref); 1096 ret = PTR_ERR(key_ref);
1089 goto error; 1097 goto error;
@@ -1170,7 +1178,7 @@ long keyctl_get_security(key_serial_t keyid,
1170 char *context; 1178 char *context;
1171 long ret; 1179 long ret;
1172 1180
1173 key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); 1181 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW);
1174 if (IS_ERR(key_ref)) { 1182 if (IS_ERR(key_ref)) {
1175 if (PTR_ERR(key_ref) != -EACCES) 1183 if (PTR_ERR(key_ref) != -EACCES)
1176 return PTR_ERR(key_ref); 1184 return PTR_ERR(key_ref);
@@ -1182,7 +1190,7 @@ long keyctl_get_security(key_serial_t keyid,
1182 return PTR_ERR(key_ref); 1190 return PTR_ERR(key_ref);
1183 key_put(instkey); 1191 key_put(instkey);
1184 1192
1185 key_ref = lookup_user_key(keyid, 0, 1, 0); 1193 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0);
1186 if (IS_ERR(key_ref)) 1194 if (IS_ERR(key_ref))
1187 return PTR_ERR(key_ref); 1195 return PTR_ERR(key_ref);
1188 } 1196 }
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index ed929af466d3..4739cfbb41b7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -487,7 +487,7 @@ static int lookup_user_key_possessed(const struct key *key, const void *target)
487 * - don't create special keyrings unless so requested 487 * - don't create special keyrings unless so requested
488 * - partially constructed keys aren't found unless requested 488 * - partially constructed keys aren't found unless requested
489 */ 489 */
490key_ref_t lookup_user_key(key_serial_t id, int create, int partial, 490key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
491 key_perm_t perm) 491 key_perm_t perm)
492{ 492{
493 struct request_key_auth *rka; 493 struct request_key_auth *rka;
@@ -503,7 +503,7 @@ try_again:
503 switch (id) { 503 switch (id) {
504 case KEY_SPEC_THREAD_KEYRING: 504 case KEY_SPEC_THREAD_KEYRING:
505 if (!cred->thread_keyring) { 505 if (!cred->thread_keyring) {
506 if (!create) 506 if (!(lflags & KEY_LOOKUP_CREATE))
507 goto error; 507 goto error;
508 508
509 ret = install_thread_keyring(); 509 ret = install_thread_keyring();
@@ -521,7 +521,7 @@ try_again:
521 521
522 case KEY_SPEC_PROCESS_KEYRING: 522 case KEY_SPEC_PROCESS_KEYRING:
523 if (!cred->tgcred->process_keyring) { 523 if (!cred->tgcred->process_keyring) {
524 if (!create) 524 if (!(lflags & KEY_LOOKUP_CREATE))
525 goto error; 525 goto error;
526 526
527 ret = install_process_keyring(); 527 ret = install_process_keyring();
@@ -642,7 +642,14 @@ try_again:
642 break; 642 break;
643 } 643 }
644 644
645 if (!partial) { 645 /* unlink does not use the nominated key in any way, so can skip all
646 * the permission checks as it is only concerned with the keyring */
647 if (lflags & KEY_LOOKUP_FOR_UNLINK) {
648 ret = 0;
649 goto error;
650 }
651
652 if (!(lflags & KEY_LOOKUP_PARTIAL)) {
646 ret = wait_for_key_construction(key, true); 653 ret = wait_for_key_construction(key, true);
647 switch (ret) { 654 switch (ret) {
648 case -ERESTARTSYS: 655 case -ERESTARTSYS:
@@ -660,7 +667,8 @@ try_again:
660 } 667 }
661 668
662 ret = -EIO; 669 ret = -EIO;
663 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 670 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
671 !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
664 goto invalid_key; 672 goto invalid_key;
665 673
666 /* check the permissions */ 674 /* check the permissions */