diff options
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r-- | security/keys/keyring.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index c9a5de197487..90a551e4da66 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* keyring.c: keyring handling | 1 | /* keyring.c: keyring handling |
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 |
@@ -308,7 +308,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
308 | uid, gid, KEY_USR_ALL, not_in_quota); | 308 | uid, gid, KEY_USR_ALL, not_in_quota); |
309 | 309 | ||
310 | if (!IS_ERR(keyring)) { | 310 | if (!IS_ERR(keyring)) { |
311 | ret = key_instantiate_and_link(keyring, NULL, 0, dest); | 311 | ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); |
312 | if (ret < 0) { | 312 | if (ret < 0) { |
313 | key_put(keyring); | 313 | key_put(keyring); |
314 | keyring = ERR_PTR(ret); | 314 | keyring = ERR_PTR(ret); |
@@ -326,11 +326,12 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
326 | * - we only find keys on which we have search permission | 326 | * - we only find keys on which we have search permission |
327 | * - we use the supplied match function to see if the description (or other | 327 | * - we use the supplied match function to see if the description (or other |
328 | * feature of interest) matches | 328 | * feature of interest) matches |
329 | * - we readlock the keyrings as we search down the tree | 329 | * - we rely on RCU to prevent the keyring lists from disappearing on us |
330 | * - we return -EAGAIN if we didn't find any matching key | 330 | * - we return -EAGAIN if we didn't find any matching key |
331 | * - we return -ENOKEY if we only found negative matching keys | 331 | * - we return -ENOKEY if we only found negative matching keys |
332 | */ | 332 | */ |
333 | struct key *keyring_search_aux(struct key *keyring, | 333 | struct key *keyring_search_aux(struct key *keyring, |
334 | struct task_struct *context, | ||
334 | struct key_type *type, | 335 | struct key_type *type, |
335 | const void *description, | 336 | const void *description, |
336 | key_match_func_t match) | 337 | key_match_func_t match) |
@@ -352,7 +353,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
352 | 353 | ||
353 | /* top keyring must have search permission to begin the search */ | 354 | /* top keyring must have search permission to begin the search */ |
354 | key = ERR_PTR(-EACCES); | 355 | key = ERR_PTR(-EACCES); |
355 | if (!key_permission(keyring, KEY_SEARCH)) | 356 | if (!key_task_permission(keyring, context, KEY_SEARCH)) |
356 | goto error; | 357 | goto error; |
357 | 358 | ||
358 | key = ERR_PTR(-ENOTDIR); | 359 | key = ERR_PTR(-ENOTDIR); |
@@ -392,7 +393,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
392 | continue; | 393 | continue; |
393 | 394 | ||
394 | /* key must have search permissions */ | 395 | /* key must have search permissions */ |
395 | if (!key_permission(key, KEY_SEARCH)) | 396 | if (!key_task_permission(key, context, KEY_SEARCH)) |
396 | continue; | 397 | continue; |
397 | 398 | ||
398 | /* we set a different error code if we find a negative key */ | 399 | /* we set a different error code if we find a negative key */ |
@@ -418,7 +419,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
418 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) | 419 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) |
419 | continue; | 420 | continue; |
420 | 421 | ||
421 | if (!key_permission(key, KEY_SEARCH)) | 422 | if (!key_task_permission(key, context, KEY_SEARCH)) |
422 | continue; | 423 | continue; |
423 | 424 | ||
424 | /* stack the current position */ | 425 | /* stack the current position */ |
@@ -468,7 +469,11 @@ struct key *keyring_search(struct key *keyring, | |||
468 | struct key_type *type, | 469 | struct key_type *type, |
469 | const char *description) | 470 | const char *description) |
470 | { | 471 | { |
471 | return keyring_search_aux(keyring, type, description, type->match); | 472 | if (!type->match) |
473 | return ERR_PTR(-ENOKEY); | ||
474 | |||
475 | return keyring_search_aux(keyring, current, | ||
476 | type, description, type->match); | ||
472 | 477 | ||
473 | } /* end keyring_search() */ | 478 | } /* end keyring_search() */ |
474 | 479 | ||
@@ -496,7 +501,8 @@ struct key *__keyring_search_one(struct key *keyring, | |||
496 | key = klist->keys[loop]; | 501 | key = klist->keys[loop]; |
497 | 502 | ||
498 | if (key->type == ktype && | 503 | if (key->type == ktype && |
499 | key->type->match(key, description) && | 504 | (!key->type->match || |
505 | key->type->match(key, description)) && | ||
500 | key_permission(key, perm) && | 506 | key_permission(key, perm) && |
501 | !test_bit(KEY_FLAG_REVOKED, &key->flags) | 507 | !test_bit(KEY_FLAG_REVOKED, &key->flags) |
502 | ) | 508 | ) |
@@ -517,6 +523,51 @@ struct key *__keyring_search_one(struct key *keyring, | |||
517 | 523 | ||
518 | /*****************************************************************************/ | 524 | /*****************************************************************************/ |
519 | /* | 525 | /* |
526 | * search for an instantiation authorisation key matching a target key | ||
527 | * - the RCU read lock must be held by the caller | ||
528 | * - a target_id of zero specifies any valid token | ||
529 | */ | ||
530 | struct key *keyring_search_instkey(struct key *keyring, | ||
531 | key_serial_t target_id) | ||
532 | { | ||
533 | struct request_key_auth *rka; | ||
534 | struct keyring_list *klist; | ||
535 | struct key *instkey; | ||
536 | int loop; | ||
537 | |||
538 | klist = rcu_dereference(keyring->payload.subscriptions); | ||
539 | if (klist) { | ||
540 | for (loop = 0; loop < klist->nkeys; loop++) { | ||
541 | instkey = klist->keys[loop]; | ||
542 | |||
543 | if (instkey->type != &key_type_request_key_auth) | ||
544 | continue; | ||
545 | |||
546 | rka = instkey->payload.data; | ||
547 | if (target_id && rka->target_key->serial != target_id) | ||
548 | continue; | ||
549 | |||
550 | /* the auth key is revoked during instantiation */ | ||
551 | if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags)) | ||
552 | goto found; | ||
553 | |||
554 | instkey = ERR_PTR(-EKEYREVOKED); | ||
555 | goto error; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | instkey = ERR_PTR(-EACCES); | ||
560 | goto error; | ||
561 | |||
562 | found: | ||
563 | atomic_inc(&instkey->usage); | ||
564 | error: | ||
565 | return instkey; | ||
566 | |||
567 | } /* end keyring_search_instkey() */ | ||
568 | |||
569 | /*****************************************************************************/ | ||
570 | /* | ||
520 | * find a keyring with the specified name | 571 | * find a keyring with the specified name |
521 | * - all named keyrings are searched | 572 | * - all named keyrings are searched |
522 | * - only find keyrings with search permission for the process | 573 | * - only find keyrings with search permission for the process |