summaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-08 22:19:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-08 22:19:37 -0400
commitc236b6dd48dcf2ae6ed14b9068830eccc3e181e6 (patch)
tree30f5e2387f344b454a842f3c9677d7c5950871a0 /security/keys
parentd44a62742decca5ae5688a562584dc0fe9fc63f6 (diff)
parent3b8c4a08a471d56ecaaca939c972fdf5b8255629 (diff)
Merge tag 'keys-request-20190626' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull request_key improvements from David Howells: "These are all request_key()-related, including a fix and some improvements: - Fix the lack of a Link permission check on a key found by request_key(), thereby enabling request_key() to link keys that don't grant this permission to the target keyring (which must still grant Write permission). Note that the key must be in the caller's keyrings already to be found. - Invalidate used request_key authentication keys rather than revoking them, so that they get cleaned up immediately rather than hanging around till the expiry time is passed. - Move the RCU locks outwards from the keyring search functions so that a request_key_rcu() can be provided. This can be called in RCU mode, so it can't sleep and can't upcall - but it can be called from LOOKUP_RCU pathwalk mode. - Cache the latest positive result of request_key*() temporarily in task_struct so that filesystems that make a lot of request_key() calls during pathwalk can take advantage of it to avoid having to redo the searching. This requires CONFIG_KEYS_REQUEST_CACHE=y. It is assumed that the key just found is likely to be used multiple times in each step in an RCU pathwalk, and is likely to be reused for the next step too. Note that the cleanup of the cache is done on TIF_NOTIFY_RESUME, just before userspace resumes, and on exit" * tag 'keys-request-20190626' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: keys: Kill off request_key_async{,_with_auxdata} keys: Cache result of request_key*() temporarily in task_struct keys: Provide request_key_rcu() keys: Move the RCU locks outwards from the keyring search functions keys: Invalidate used request_key authentication keys keys: Fix request_key() lack of Link perm check on found key
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Kconfig18
-rw-r--r--security/keys/internal.h6
-rw-r--r--security/keys/key.c4
-rw-r--r--security/keys/keyring.c16
-rw-r--r--security/keys/proc.c4
-rw-r--r--security/keys/process_keys.c41
-rw-r--r--security/keys/request_key.c137
-rw-r--r--security/keys/request_key_auth.c60
8 files changed, 180 insertions, 106 deletions
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index ee502e4d390b..dd313438fecf 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -25,6 +25,24 @@ config KEYS_COMPAT
25 def_bool y 25 def_bool y
26 depends on COMPAT && KEYS 26 depends on COMPAT && KEYS
27 27
28config KEYS_REQUEST_CACHE
29 bool "Enable temporary caching of the last request_key() result"
30 depends on KEYS
31 help
32 This option causes the result of the last successful request_key()
33 call that didn't upcall to the kernel to be cached temporarily in the
34 task_struct. The cache is cleared by exit and just prior to the
35 resumption of userspace.
36
37 This allows the key used for multiple step processes where each step
38 wants to request a key that is likely the same as the one requested
39 by the last step to save on the searching.
40
41 An example of such a process is a pathwalk through a network
42 filesystem in which each method needs to request an authentication
43 key. Pathwalk will call multiple methods for each dentry traversed
44 (permission, d_revalidate, lookup, getxattr, getacl, ...).
45
28config PERSISTENT_KEYRINGS 46config PERSISTENT_KEYRINGS
29 bool "Enable register of persistent per-UID keyrings" 47 bool "Enable register of persistent per-UID keyrings"
30 depends on KEYS 48 depends on KEYS
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 0f48b53754b3..663f291e30d4 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -135,11 +135,11 @@ struct keyring_search_context {
135 135
136extern bool key_default_cmp(const struct key *key, 136extern bool key_default_cmp(const struct key *key,
137 const struct key_match_data *match_data); 137 const struct key_match_data *match_data);
138extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 138extern key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
139 struct keyring_search_context *ctx); 139 struct keyring_search_context *ctx);
140 140
141extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); 141extern key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx);
142extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); 142extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx);
143 143
144extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); 144extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
145 145
diff --git a/security/keys/key.c b/security/keys/key.c
index d3c17d76ea76..85dddc0190a7 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -455,7 +455,7 @@ static int __key_instantiate_and_link(struct key *key,
455 455
456 /* disable the authorisation key */ 456 /* disable the authorisation key */
457 if (authkey) 457 if (authkey)
458 key_revoke(authkey); 458 key_invalidate(authkey);
459 459
460 if (prep->expiry != TIME64_MAX) { 460 if (prep->expiry != TIME64_MAX) {
461 key->expiry = prep->expiry; 461 key->expiry = prep->expiry;
@@ -612,7 +612,7 @@ int key_reject_and_link(struct key *key,
612 612
613 /* disable the authorisation key */ 613 /* disable the authorisation key */
614 if (authkey) 614 if (authkey)
615 key_revoke(authkey); 615 key_invalidate(authkey);
616 } 616 }
617 617
618 mutex_unlock(&key_construction_mutex); 618 mutex_unlock(&key_construction_mutex);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 204b5a4d180e..e4de4070c754 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -831,7 +831,7 @@ found:
831} 831}
832 832
833/** 833/**
834 * keyring_search_aux - Search a keyring tree for a key matching some criteria 834 * keyring_search_rcu - Search a keyring tree for a matching key under RCU
835 * @keyring_ref: A pointer to the keyring with possession indicator. 835 * @keyring_ref: A pointer to the keyring with possession indicator.
836 * @ctx: The keyring search context. 836 * @ctx: The keyring search context.
837 * 837 *
@@ -843,7 +843,9 @@ found:
843 * addition, the LSM gets to forbid keyring searches and key matches. 843 * addition, the LSM gets to forbid keyring searches and key matches.
844 * 844 *
845 * The search is performed as a breadth-then-depth search up to the prescribed 845 * The search is performed as a breadth-then-depth search up to the prescribed
846 * limit (KEYRING_SEARCH_MAX_DEPTH). 846 * limit (KEYRING_SEARCH_MAX_DEPTH). The caller must hold the RCU read lock to
847 * prevent keyrings from being destroyed or rearranged whilst they are being
848 * searched.
847 * 849 *
848 * Keys are matched to the type provided and are then filtered by the match 850 * Keys are matched to the type provided and are then filtered by the match
849 * function, which is given the description to use in any way it sees fit. The 851 * function, which is given the description to use in any way it sees fit. The
@@ -862,7 +864,7 @@ found:
862 * In the case of a successful return, the possession attribute from 864 * In the case of a successful return, the possession attribute from
863 * @keyring_ref is propagated to the returned key reference. 865 * @keyring_ref is propagated to the returned key reference.
864 */ 866 */
865key_ref_t keyring_search_aux(key_ref_t keyring_ref, 867key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
866 struct keyring_search_context *ctx) 868 struct keyring_search_context *ctx)
867{ 869{
868 struct key *keyring; 870 struct key *keyring;
@@ -884,11 +886,9 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
884 return ERR_PTR(err); 886 return ERR_PTR(err);
885 } 887 }
886 888
887 rcu_read_lock();
888 ctx->now = ktime_get_real_seconds(); 889 ctx->now = ktime_get_real_seconds();
889 if (search_nested_keyrings(keyring, ctx)) 890 if (search_nested_keyrings(keyring, ctx))
890 __key_get(key_ref_to_ptr(ctx->result)); 891 __key_get(key_ref_to_ptr(ctx->result));
891 rcu_read_unlock();
892 return ctx->result; 892 return ctx->result;
893} 893}
894 894
@@ -898,7 +898,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
898 * @type: The type of keyring we want to find. 898 * @type: The type of keyring we want to find.
899 * @description: The name of the keyring we want to find. 899 * @description: The name of the keyring we want to find.
900 * 900 *
901 * As keyring_search_aux() above, but using the current task's credentials and 901 * As keyring_search_rcu() above, but using the current task's credentials and
902 * type's default matching function and preferred search method. 902 * type's default matching function and preferred search method.
903 */ 903 */
904key_ref_t keyring_search(key_ref_t keyring, 904key_ref_t keyring_search(key_ref_t keyring,
@@ -924,7 +924,9 @@ key_ref_t keyring_search(key_ref_t keyring,
924 return ERR_PTR(ret); 924 return ERR_PTR(ret);
925 } 925 }
926 926
927 key = keyring_search_aux(keyring, &ctx); 927 rcu_read_lock();
928 key = keyring_search_rcu(keyring, &ctx);
929 rcu_read_unlock();
928 930
929 if (type->match_free) 931 if (type->match_free)
930 type->match_free(&ctx.match_data); 932 type->match_free(&ctx.match_data);
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 4e3266a2529e..7f15550c10f5 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -175,7 +175,9 @@ static int proc_keys_show(struct seq_file *m, void *v)
175 * skip if the key does not indicate the possessor can view it 175 * skip if the key does not indicate the possessor can view it
176 */ 176 */
177 if (key->perm & KEY_POS_VIEW) { 177 if (key->perm & KEY_POS_VIEW) {
178 skey_ref = search_my_process_keyrings(&ctx); 178 rcu_read_lock();
179 skey_ref = search_cred_keyrings_rcu(&ctx);
180 rcu_read_unlock();
179 if (!IS_ERR(skey_ref)) { 181 if (!IS_ERR(skey_ref)) {
180 key_ref_put(skey_ref); 182 key_ref_put(skey_ref);
181 key_ref = make_key_ref(key, 1); 183 key_ref = make_key_ref(key, 1);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a40b33614208..b99ad2c5342f 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -314,7 +314,8 @@ void key_fsgid_changed(struct cred *new_cred)
314 314
315/* 315/*
316 * Search the process keyrings attached to the supplied cred for the first 316 * Search the process keyrings attached to the supplied cred for the first
317 * matching key. 317 * matching key under RCU conditions (the caller must be holding the RCU read
318 * lock).
318 * 319 *
319 * The search criteria are the type and the match function. The description is 320 * The search criteria are the type and the match function. The description is
320 * given to the match function as a parameter, but doesn't otherwise influence 321 * given to the match function as a parameter, but doesn't otherwise influence
@@ -333,7 +334,7 @@ void key_fsgid_changed(struct cred *new_cred)
333 * In the case of a successful return, the possession attribute is set on the 334 * In the case of a successful return, the possession attribute is set on the
334 * returned key reference. 335 * returned key reference.
335 */ 336 */
336key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) 337key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx)
337{ 338{
338 key_ref_t key_ref, ret, err; 339 key_ref_t key_ref, ret, err;
339 const struct cred *cred = ctx->cred; 340 const struct cred *cred = ctx->cred;
@@ -351,7 +352,7 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
351 352
352 /* search the thread keyring first */ 353 /* search the thread keyring first */
353 if (cred->thread_keyring) { 354 if (cred->thread_keyring) {
354 key_ref = keyring_search_aux( 355 key_ref = keyring_search_rcu(
355 make_key_ref(cred->thread_keyring, 1), ctx); 356 make_key_ref(cred->thread_keyring, 1), ctx);
356 if (!IS_ERR(key_ref)) 357 if (!IS_ERR(key_ref))
357 goto found; 358 goto found;
@@ -369,7 +370,7 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
369 370
370 /* search the process keyring second */ 371 /* search the process keyring second */
371 if (cred->process_keyring) { 372 if (cred->process_keyring) {
372 key_ref = keyring_search_aux( 373 key_ref = keyring_search_rcu(
373 make_key_ref(cred->process_keyring, 1), ctx); 374 make_key_ref(cred->process_keyring, 1), ctx);
374 if (!IS_ERR(key_ref)) 375 if (!IS_ERR(key_ref))
375 goto found; 376 goto found;
@@ -390,7 +391,7 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
390 391
391 /* search the session keyring */ 392 /* search the session keyring */
392 if (cred->session_keyring) { 393 if (cred->session_keyring) {
393 key_ref = keyring_search_aux( 394 key_ref = keyring_search_rcu(
394 make_key_ref(cred->session_keyring, 1), ctx); 395 make_key_ref(cred->session_keyring, 1), ctx);
395 396
396 if (!IS_ERR(key_ref)) 397 if (!IS_ERR(key_ref))
@@ -411,7 +412,7 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
411 } 412 }
412 /* or search the user-session keyring */ 413 /* or search the user-session keyring */
413 else if (READ_ONCE(cred->user->session_keyring)) { 414 else if (READ_ONCE(cred->user->session_keyring)) {
414 key_ref = keyring_search_aux( 415 key_ref = keyring_search_rcu(
415 make_key_ref(READ_ONCE(cred->user->session_keyring), 1), 416 make_key_ref(READ_ONCE(cred->user->session_keyring), 1),
416 ctx); 417 ctx);
417 if (!IS_ERR(key_ref)) 418 if (!IS_ERR(key_ref))
@@ -444,16 +445,16 @@ found:
444 * the keys attached to the assumed authorisation key using its credentials if 445 * the keys attached to the assumed authorisation key using its credentials if
445 * one is available. 446 * one is available.
446 * 447 *
447 * Return same as search_my_process_keyrings(). 448 * The caller must be holding the RCU read lock.
449 *
450 * Return same as search_cred_keyrings_rcu().
448 */ 451 */
449key_ref_t search_process_keyrings(struct keyring_search_context *ctx) 452key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx)
450{ 453{
451 struct request_key_auth *rka; 454 struct request_key_auth *rka;
452 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; 455 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
453 456
454 might_sleep(); 457 key_ref = search_cred_keyrings_rcu(ctx);
455
456 key_ref = search_my_process_keyrings(ctx);
457 if (!IS_ERR(key_ref)) 458 if (!IS_ERR(key_ref))
458 goto found; 459 goto found;
459 err = key_ref; 460 err = key_ref;
@@ -468,24 +469,17 @@ key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
468 ) { 469 ) {
469 const struct cred *cred = ctx->cred; 470 const struct cred *cred = ctx->cred;
470 471
471 /* defend against the auth key being revoked */ 472 if (key_validate(cred->request_key_auth) == 0) {
472 down_read(&cred->request_key_auth->sem);
473
474 if (key_validate(ctx->cred->request_key_auth) == 0) {
475 rka = ctx->cred->request_key_auth->payload.data[0]; 473 rka = ctx->cred->request_key_auth->payload.data[0];
476 474
475 //// was search_process_keyrings() [ie. recursive]
477 ctx->cred = rka->cred; 476 ctx->cred = rka->cred;
478 key_ref = search_process_keyrings(ctx); 477 key_ref = search_cred_keyrings_rcu(ctx);
479 ctx->cred = cred; 478 ctx->cred = cred;
480 479
481 up_read(&cred->request_key_auth->sem);
482
483 if (!IS_ERR(key_ref)) 480 if (!IS_ERR(key_ref))
484 goto found; 481 goto found;
485
486 ret = key_ref; 482 ret = key_ref;
487 } else {
488 up_read(&cred->request_key_auth->sem);
489 } 483 }
490 } 484 }
491 485
@@ -500,7 +494,6 @@ key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
500found: 494found:
501 return key_ref; 495 return key_ref;
502} 496}
503
504/* 497/*
505 * See if the key we're looking at is the target key. 498 * See if the key we're looking at is the target key.
506 */ 499 */
@@ -687,7 +680,9 @@ try_again:
687 ctx.index_key = key->index_key; 680 ctx.index_key = key->index_key;
688 ctx.match_data.raw_data = key; 681 ctx.match_data.raw_data = key;
689 kdebug("check possessed"); 682 kdebug("check possessed");
690 skey_ref = search_process_keyrings(&ctx); 683 rcu_read_lock();
684 skey_ref = search_process_keyrings_rcu(&ctx);
685 rcu_read_unlock();
691 kdebug("possessed=%p", skey_ref); 686 kdebug("possessed=%p", skey_ref);
692 687
693 if (!IS_ERR(skey_ref)) { 688 if (!IS_ERR(skey_ref)) {
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index fcef7e26b94b..f2b4da143963 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -18,6 +18,31 @@
18 18
19#define key_negative_timeout 60 /* default timeout on a negative key's existence */ 19#define key_negative_timeout 60 /* default timeout on a negative key's existence */
20 20
21static struct key *check_cached_key(struct keyring_search_context *ctx)
22{
23#ifdef CONFIG_KEYS_REQUEST_CACHE
24 struct key *key = current->cached_requested_key;
25
26 if (key &&
27 ctx->match_data.cmp(key, &ctx->match_data) &&
28 !(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
29 (1 << KEY_FLAG_REVOKED))))
30 return key_get(key);
31#endif
32 return NULL;
33}
34
35static void cache_requested_key(struct key *key)
36{
37#ifdef CONFIG_KEYS_REQUEST_CACHE
38 struct task_struct *t = current;
39
40 key_put(t->cached_requested_key);
41 t->cached_requested_key = key_get(key);
42 set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
43#endif
44}
45
21/** 46/**
22 * complete_request_key - Complete the construction of a key. 47 * complete_request_key - Complete the construction of a key.
23 * @authkey: The authorisation key. 48 * @authkey: The authorisation key.
@@ -218,7 +243,7 @@ static int construct_key(struct key *key, const void *callout_info,
218 /* check that the actor called complete_request_key() prior to 243 /* check that the actor called complete_request_key() prior to
219 * returning an error */ 244 * returning an error */
220 WARN_ON(ret < 0 && 245 WARN_ON(ret < 0 &&
221 !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); 246 !test_bit(KEY_FLAG_INVALIDATED, &authkey->flags));
222 247
223 key_put(authkey); 248 key_put(authkey);
224 kleave(" = %d", ret); 249 kleave(" = %d", ret);
@@ -381,7 +406,9 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
381 * waited for locks */ 406 * waited for locks */
382 mutex_lock(&key_construction_mutex); 407 mutex_lock(&key_construction_mutex);
383 408
384 key_ref = search_process_keyrings(ctx); 409 rcu_read_lock();
410 key_ref = search_process_keyrings_rcu(ctx);
411 rcu_read_unlock();
385 if (!IS_ERR(key_ref)) 412 if (!IS_ERR(key_ref))
386 goto key_already_present; 413 goto key_already_present;
387 414
@@ -556,10 +583,26 @@ struct key *request_key_and_link(struct key_type *type,
556 } 583 }
557 } 584 }
558 585
586 key = check_cached_key(&ctx);
587 if (key)
588 return key;
589
559 /* search all the process keyrings for a key */ 590 /* search all the process keyrings for a key */
560 key_ref = search_process_keyrings(&ctx); 591 rcu_read_lock();
592 key_ref = search_process_keyrings_rcu(&ctx);
593 rcu_read_unlock();
561 594
562 if (!IS_ERR(key_ref)) { 595 if (!IS_ERR(key_ref)) {
596 if (dest_keyring) {
597 ret = key_task_permission(key_ref, current_cred(),
598 KEY_NEED_LINK);
599 if (ret < 0) {
600 key_ref_put(key_ref);
601 key = ERR_PTR(ret);
602 goto error_free;
603 }
604 }
605
563 key = key_ref_to_ptr(key_ref); 606 key = key_ref_to_ptr(key_ref);
564 if (dest_keyring) { 607 if (dest_keyring) {
565 ret = key_link(dest_keyring, key); 608 ret = key_link(dest_keyring, key);
@@ -569,6 +612,9 @@ struct key *request_key_and_link(struct key_type *type,
569 goto error_free; 612 goto error_free;
570 } 613 }
571 } 614 }
615
616 /* Only cache the key on immediate success */
617 cache_requested_key(key);
572 } else if (PTR_ERR(key_ref) != -EAGAIN) { 618 } else if (PTR_ERR(key_ref) != -EAGAIN) {
573 key = ERR_CAST(key_ref); 619 key = ERR_CAST(key_ref);
574 } else { 620 } else {
@@ -689,52 +735,51 @@ struct key *request_key_with_auxdata(struct key_type *type,
689} 735}
690EXPORT_SYMBOL(request_key_with_auxdata); 736EXPORT_SYMBOL(request_key_with_auxdata);
691 737
692/* 738/**
693 * request_key_async - Request a key (allow async construction) 739 * request_key_rcu - Request key from RCU-read-locked context
694 * @type: Type of key. 740 * @type: The type of key we want.
695 * @description: The searchable description of the key. 741 * @description: The name of the key we want.
696 * @callout_info: The data to pass to the instantiation upcall (or NULL).
697 * @callout_len: The length of callout_info.
698 * 742 *
699 * As for request_key_and_link() except that it does not add the returned key 743 * Request a key from a context that we may not sleep in (such as RCU-mode
700 * to a keyring if found, new keys are always allocated in the user's quota and 744 * pathwalk). Keys under construction are ignored.
701 * no auxiliary data can be passed.
702 * 745 *
703 * The caller should call wait_for_key_construction() to wait for the 746 * Return a pointer to the found key if successful, -ENOKEY if we couldn't find
704 * completion of the returned key if it is still undergoing construction. 747 * a key or some other error if the key found was unsuitable or inaccessible.
705 */ 748 */
706struct key *request_key_async(struct key_type *type, 749struct key *request_key_rcu(struct key_type *type, const char *description)
707 const char *description,
708 const void *callout_info,
709 size_t callout_len)
710{ 750{
711 return request_key_and_link(type, description, callout_info, 751 struct keyring_search_context ctx = {
712 callout_len, NULL, NULL, 752 .index_key.type = type,
713 KEY_ALLOC_IN_QUOTA); 753 .index_key.description = description,
714} 754 .index_key.desc_len = strlen(description),
715EXPORT_SYMBOL(request_key_async); 755 .cred = current_cred(),
756 .match_data.cmp = key_default_cmp,
757 .match_data.raw_data = description,
758 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
759 .flags = (KEYRING_SEARCH_DO_STATE_CHECK |
760 KEYRING_SEARCH_SKIP_EXPIRED),
761 };
762 struct key *key;
763 key_ref_t key_ref;
716 764
717/* 765 kenter("%s,%s", type->name, description);
718 * request a key with auxiliary data for the upcaller (allow async construction) 766
719 * @type: Type of key. 767 key = check_cached_key(&ctx);
720 * @description: The searchable description of the key. 768 if (key)
721 * @callout_info: The data to pass to the instantiation upcall (or NULL). 769 return key;
722 * @callout_len: The length of callout_info. 770
723 * @aux: Auxiliary data for the upcall. 771 /* search all the process keyrings for a key */
724 * 772 key_ref = search_process_keyrings_rcu(&ctx);
725 * As for request_key_and_link() except that it does not add the returned key 773 if (IS_ERR(key_ref)) {
726 * to a keyring if found and new keys are always allocated in the user's quota. 774 key = ERR_CAST(key_ref);
727 * 775 if (PTR_ERR(key_ref) == -EAGAIN)
728 * The caller should call wait_for_key_construction() to wait for the 776 key = ERR_PTR(-ENOKEY);
729 * completion of the returned key if it is still undergoing construction. 777 } else {
730 */ 778 key = key_ref_to_ptr(key_ref);
731struct key *request_key_async_with_auxdata(struct key_type *type, 779 cache_requested_key(key);
732 const char *description, 780 }
733 const void *callout_info, 781
734 size_t callout_len, 782 kleave(" = %p", key);
735 void *aux) 783 return key;
736{
737 return request_key_and_link(type, description, callout_info,
738 callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
739} 784}
740EXPORT_SYMBOL(request_key_async_with_auxdata); 785EXPORT_SYMBOL(request_key_rcu);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 3d8616f981b2..5456c0c72857 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -54,7 +54,7 @@ static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
54static int request_key_auth_instantiate(struct key *key, 54static int request_key_auth_instantiate(struct key *key,
55 struct key_preparsed_payload *prep) 55 struct key_preparsed_payload *prep)
56{ 56{
57 key->payload.data[0] = (struct request_key_auth *)prep->data; 57 rcu_assign_keypointer(key, (struct request_key_auth *)prep->data);
58 return 0; 58 return 0;
59} 59}
60 60
@@ -64,7 +64,7 @@ static int request_key_auth_instantiate(struct key *key,
64static void request_key_auth_describe(const struct key *key, 64static void request_key_auth_describe(const struct key *key,
65 struct seq_file *m) 65 struct seq_file *m)
66{ 66{
67 struct request_key_auth *rka = get_request_key_auth(key); 67 struct request_key_auth *rka = dereference_key_rcu(key);
68 68
69 seq_puts(m, "key:"); 69 seq_puts(m, "key:");
70 seq_puts(m, key->description); 70 seq_puts(m, key->description);
@@ -79,7 +79,7 @@ static void request_key_auth_describe(const struct key *key,
79static long request_key_auth_read(const struct key *key, 79static long request_key_auth_read(const struct key *key,
80 char __user *buffer, size_t buflen) 80 char __user *buffer, size_t buflen)
81{ 81{
82 struct request_key_auth *rka = get_request_key_auth(key); 82 struct request_key_auth *rka = dereference_key_locked(key);
83 size_t datalen; 83 size_t datalen;
84 long ret; 84 long ret;
85 85
@@ -98,23 +98,6 @@ static long request_key_auth_read(const struct key *key,
98 return ret; 98 return ret;
99} 99}
100 100
101/*
102 * Handle revocation of an authorisation token key.
103 *
104 * Called with the key sem write-locked.
105 */
106static void request_key_auth_revoke(struct key *key)
107{
108 struct request_key_auth *rka = get_request_key_auth(key);
109
110 kenter("{%d}", key->serial);
111
112 if (rka->cred) {
113 put_cred(rka->cred);
114 rka->cred = NULL;
115 }
116}
117
118static void free_request_key_auth(struct request_key_auth *rka) 101static void free_request_key_auth(struct request_key_auth *rka)
119{ 102{
120 if (!rka) 103 if (!rka)
@@ -128,15 +111,42 @@ static void free_request_key_auth(struct request_key_auth *rka)
128} 111}
129 112
130/* 113/*
114 * Dispose of the request_key_auth record under RCU conditions
115 */
116static void request_key_auth_rcu_disposal(struct rcu_head *rcu)
117{
118 struct request_key_auth *rka =
119 container_of(rcu, struct request_key_auth, rcu);
120
121 free_request_key_auth(rka);
122}
123
124/*
125 * Handle revocation of an authorisation token key.
126 *
127 * Called with the key sem write-locked.
128 */
129static void request_key_auth_revoke(struct key *key)
130{
131 struct request_key_auth *rka = dereference_key_locked(key);
132
133 kenter("{%d}", key->serial);
134 rcu_assign_keypointer(key, NULL);
135 call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
136}
137
138/*
131 * Destroy an instantiation authorisation token key. 139 * Destroy an instantiation authorisation token key.
132 */ 140 */
133static void request_key_auth_destroy(struct key *key) 141static void request_key_auth_destroy(struct key *key)
134{ 142{
135 struct request_key_auth *rka = get_request_key_auth(key); 143 struct request_key_auth *rka = rcu_access_pointer(key->payload.rcu_data0);
136 144
137 kenter("{%d}", key->serial); 145 kenter("{%d}", key->serial);
138 146 if (rka) {
139 free_request_key_auth(rka); 147 rcu_assign_keypointer(key, NULL);
148 call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
149 }
140} 150}
141 151
142/* 152/*
@@ -245,7 +255,9 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
245 255
246 ctx.index_key.desc_len = sprintf(description, "%x", target_id); 256 ctx.index_key.desc_len = sprintf(description, "%x", target_id);
247 257
248 authkey_ref = search_process_keyrings(&ctx); 258 rcu_read_lock();
259 authkey_ref = search_process_keyrings_rcu(&ctx);
260 rcu_read_unlock();
249 261
250 if (IS_ERR(authkey_ref)) { 262 if (IS_ERR(authkey_ref)) {
251 authkey = ERR_CAST(authkey_ref); 263 authkey = ERR_CAST(authkey_ref);