aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c67
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 */
333struct key *keyring_search_aux(struct key *keyring, 333struct 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 */
530struct 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
562found:
563 atomic_inc(&instkey->usage);
564error:
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