diff options
author | David Howells <dhowells@redhat.com> | 2009-09-02 04:13:45 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-09-02 07:29:04 -0400 |
commit | 5593122eec26b061cc0b6fbff32118f1aadf4a27 (patch) | |
tree | f148b182ada54b722962607567bd5b1ace06640a /security/keys/keyctl.c | |
parent | e0e817392b9acf2c98d3be80c233dddb1b52003d (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>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 50 |
1 files changed, 29 insertions, 21 deletions
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, | |||
233 | long keyctl_get_keyring_ID(key_serial_t id, int create) | 234 | long 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 | } |