aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2005-09-28 12:03:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-28 12:10:47 -0400
commit664cceb0093b755739e56572b836a99104ee8a75 (patch)
treedbaa3ab802803879f29532db4d8a91a54294cf88 /security/keys/request_key.c
parent5134fc15b643dc36eb9aa77e4318b886844a9ac5 (diff)
[PATCH] Keys: Add possessor permissions to keys [try #3]
The attached patch adds extra permission grants to keys for the possessor of a key in addition to the owner, group and other permissions bits. This makes SUID binaries easier to support without going as far as labelling keys and key targets using the LSM facilities. This patch adds a second "pointer type" to key structures (struct key_ref *) that can have the bottom bit of the address set to indicate the possession of a key. This is propagated through searches from the keyring to the discovered key. It has been made a separate type so that the compiler can spot attempts to dereference a potentially incorrect pointer. The "possession" attribute can't be attached to a key structure directly as it's not an intrinsic property of a key. Pointers to keys have been replaced with struct key_ref *'s wherever possession information needs to be passed through. This does assume that the bottom bit of the pointer will always be zero on return from kmem_cache_alloc(). The key reference type has been made into a typedef so that at least it can be located in the sources, even though it's basically a pointer to an undefined type. I've also renamed the accessor functions to be more useful, and all reference variables should now end in "_ref". Signed-Off-By: David Howells <dhowells@redhat.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 90c1506d007c..e6dd366d43a3 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -129,7 +129,7 @@ static struct key *__request_key_construction(struct key_type *type,
129 129
130 /* create a key and add it to the queue */ 130 /* create a key and add it to the queue */
131 key = key_alloc(type, description, 131 key = key_alloc(type, description,
132 current->fsuid, current->fsgid, KEY_USR_ALL, 0); 132 current->fsuid, current->fsgid, KEY_POS_ALL, 0);
133 if (IS_ERR(key)) 133 if (IS_ERR(key))
134 goto alloc_failed; 134 goto alloc_failed;
135 135
@@ -365,14 +365,24 @@ struct key *request_key_and_link(struct key_type *type,
365{ 365{
366 struct key_user *user; 366 struct key_user *user;
367 struct key *key; 367 struct key *key;
368 key_ref_t key_ref;
368 369
369 kenter("%s,%s,%s,%p", 370 kenter("%s,%s,%s,%p",
370 type->name, description, callout_info, dest_keyring); 371 type->name, description, callout_info, dest_keyring);
371 372
372 /* search all the process keyrings for a key */ 373 /* search all the process keyrings for a key */
373 key = search_process_keyrings(type, description, type->match, current); 374 key_ref = search_process_keyrings(type, description, type->match,
375 current);
374 376
375 if (PTR_ERR(key) == -EAGAIN) { 377 kdebug("search 1: %p", key_ref);
378
379 if (!IS_ERR(key_ref)) {
380 key = key_ref_to_ptr(key_ref);
381 }
382 else if (PTR_ERR(key_ref) != -EAGAIN) {
383 key = ERR_PTR(PTR_ERR(key_ref));
384 }
385 else {
376 /* the search failed, but the keyrings were searchable, so we 386 /* the search failed, but the keyrings were searchable, so we
377 * should consult userspace if we can */ 387 * should consult userspace if we can */
378 key = ERR_PTR(-ENOKEY); 388 key = ERR_PTR(-ENOKEY);
@@ -384,7 +394,7 @@ struct key *request_key_and_link(struct key_type *type,
384 if (!user) 394 if (!user)
385 goto nomem; 395 goto nomem;
386 396
387 do { 397 for (;;) {
388 if (signal_pending(current)) 398 if (signal_pending(current))
389 goto interrupted; 399 goto interrupted;
390 400
@@ -397,10 +407,22 @@ struct key *request_key_and_link(struct key_type *type,
397 407
398 /* someone else made the key we want, so we need to 408 /* someone else made the key we want, so we need to
399 * search again as it might now be available to us */ 409 * search again as it might now be available to us */
400 key = search_process_keyrings(type, description, 410 key_ref = search_process_keyrings(type, description,
401 type->match, current); 411 type->match,
412 current);
413
414 kdebug("search 2: %p", key_ref);
402 415
403 } while (PTR_ERR(key) == -EAGAIN); 416 if (!IS_ERR(key_ref)) {
417 key = key_ref_to_ptr(key_ref);
418 break;
419 }
420
421 if (PTR_ERR(key_ref) != -EAGAIN) {
422 key = ERR_PTR(PTR_ERR(key_ref));
423 break;
424 }
425 }
404 426
405 key_user_put(user); 427 key_user_put(user);
406 428