Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+229 -164
+10 -28
Documentation/security/keys/core.rst
··· 433 433 /sbin/request-key will be invoked in an attempt to obtain a key. The 434 434 callout_info string will be passed as an argument to the program. 435 435 436 + To link a key into the destination keyring the key must grant link 437 + permission on the key to the caller and the keyring must grant write 438 + permission. 439 + 436 440 See also Documentation/security/keys/request-key.rst. 437 441 438 442 ··· 1115 1111 is a blob of length callout_len, if given (the length may be 0). 1116 1112 1117 1113 1118 - * A key can be requested asynchronously by calling one of:: 1114 + * To search for a key under RCU conditions, call:: 1119 1115 1120 - struct key *request_key_async(const struct key_type *type, 1121 - const char *description, 1122 - const void *callout_info, 1123 - size_t callout_len); 1116 + struct key *request_key_rcu(const struct key_type *type, 1117 + const char *description); 1124 1118 1125 - or:: 1126 - 1127 - struct key *request_key_async_with_auxdata(const struct key_type *type, 1128 - const char *description, 1129 - const char *callout_info, 1130 - size_t callout_len, 1131 - void *aux); 1132 - 1133 - which are asynchronous equivalents of request_key() and 1134 - request_key_with_auxdata() respectively. 1135 - 1136 - These two functions return with the key potentially still under 1137 - construction. To wait for construction completion, the following should be 1138 - called:: 1139 - 1140 - int wait_for_key_construction(struct key *key, bool intr); 1141 - 1142 - The function will wait for the key to finish being constructed and then 1143 - invokes key_validate() to return an appropriate value to indicate the state 1144 - of the key (0 indicates the key is usable). 1145 - 1146 - If intr is true, then the wait can be interrupted by a signal, in which 1147 - case error ERESTARTSYS will be returned. 1119 + which is similar to request_key() except that it does not check for keys 1120 + that are under construction and it will not call out to userspace to 1121 + construct a key if it can't find a match. 1148 1122 1149 1123 1150 1124 * When it is no longer required, the key should be released using::
+14 -19
Documentation/security/keys/request-key.rst
··· 23 23 24 24 or:: 25 25 26 - struct key *request_key_async(const struct key_type *type, 27 - const char *description, 28 - const char *callout_info, 29 - size_t callout_len); 30 - 31 - or:: 32 - 33 - struct key *request_key_async_with_auxdata(const struct key_type *type, 34 - const char *description, 35 - const char *callout_info, 36 - size_t callout_len, 37 - void *aux); 26 + struct key *request_key_rcu(const struct key_type *type, 27 + const char *description); 38 28 39 29 Or by userspace invoking the request_key system call:: 40 30 ··· 38 48 destroyed. The kernel interface returns a pointer directly to the key, and 39 49 it's up to the caller to destroy the key. 40 50 41 - The request_key*_with_auxdata() calls are like the in-kernel request_key*() 42 - calls, except that they permit auxiliary data to be passed to the upcaller (the 51 + The request_key_with_auxdata() calls is like the in-kernel request_key() call, 52 + except that they permit auxiliary data to be passed to the upcaller (the 43 53 default is NULL). This is only useful for those key types that define their 44 54 own upcall mechanism rather than using /sbin/request-key. 45 55 46 - The two async in-kernel calls may return keys that are still in the process of 47 - being constructed. The two non-async ones will wait for construction to 48 - complete first. 56 + The request_key_rcu() call is like the in-kernel request_key() call, except 57 + that it doesn't check for keys that are under construction and doesn't attempt 58 + to construct missing keys. 49 59 50 60 The userspace interface links the key to a keyring associated with the process 51 61 to prevent the key from going away, and returns the serial number of the key to ··· 138 148 139 149 A search of any particular keyring proceeds in the following fashion: 140 150 141 - 1) When the key management code searches for a key (keyring_search_aux) it 151 + 1) When the key management code searches for a key (keyring_search_rcu) it 142 152 firstly calls key_permission(SEARCH) on the keyring it's starting with, 143 153 if this denies permission, it doesn't search further. 144 154 ··· 156 166 The process stops immediately a valid key is found with permission granted to 157 167 use it. Any error from a previous match attempt is discarded and the key is 158 168 returned. 169 + 170 + When request_key() is invoked, if CONFIG_KEYS_REQUEST_CACHE=y, a per-task 171 + one-key cache is first checked for a match. 159 172 160 173 When search_process_keyrings() is invoked, it performs the following searches 161 174 until one succeeds: ··· 179 186 c) The calling process's session keyring is searched. 180 187 181 188 The moment one succeeds, all pending errors are discarded and the found key is 182 - returned. 189 + returned. If CONFIG_KEYS_REQUEST_CACHE=y, then that key is placed in the 190 + per-task cache, displacing the previous key. The cache is cleared on exit or 191 + just prior to resumption of userspace. 183 192 184 193 Only if all these fail does the whole thing fail with the highest priority 185 194 error. Note that several errors may have come from LSM.
+1
include/keys/request_key_auth-type.h
··· 14 14 * Authorisation record for request_key(). 15 15 */ 16 16 struct request_key_auth { 17 + struct rcu_head rcu; 17 18 struct key *target_key; 18 19 struct key *dest_keyring; 19 20 const struct cred *cred;
+3 -11
include/linux/key.h
··· 269 269 const char *description, 270 270 const char *callout_info); 271 271 272 + extern struct key *request_key_rcu(struct key_type *type, 273 + const char *description); 274 + 272 275 extern struct key *request_key_with_auxdata(struct key_type *type, 273 276 const char *description, 274 277 const void *callout_info, 275 278 size_t callout_len, 276 279 void *aux); 277 - 278 - extern struct key *request_key_async(struct key_type *type, 279 - const char *description, 280 - const void *callout_info, 281 - size_t callout_len); 282 - 283 - extern struct key *request_key_async_with_auxdata(struct key_type *type, 284 - const char *description, 285 - const void *callout_info, 286 - size_t callout_len, 287 - void *aux); 288 280 289 281 extern int wait_for_key_construction(struct key *key, bool intr); 290 282
+5
include/linux/sched.h
··· 892 892 /* Effective (overridable) subjective task credentials (COW): */ 893 893 const struct cred __rcu *cred; 894 894 895 + #ifdef CONFIG_KEYS 896 + /* Cached requested key. */ 897 + struct key *cached_requested_key; 898 + #endif 899 + 895 900 /* 896 901 * executable name, excluding path. 897 902 *
+7
include/linux/tracehook.h
··· 184 184 if (unlikely(current->task_works)) 185 185 task_work_run(); 186 186 187 + #ifdef CONFIG_KEYS_REQUEST_CACHE 188 + if (unlikely(current->cached_requested_key)) { 189 + key_put(current->cached_requested_key); 190 + current->cached_requested_key = NULL; 191 + } 192 + #endif 193 + 187 194 mem_cgroup_handle_over_high(); 188 195 blkcg_maybe_throttle_current(); 189 196 }
+9
kernel/cred.c
··· 170 170 validate_creds(cred); 171 171 alter_cred_subscribers(cred, -1); 172 172 put_cred(cred); 173 + 174 + #ifdef CONFIG_KEYS_REQUEST_CACHE 175 + key_put(current->cached_requested_key); 176 + current->cached_requested_key = NULL; 177 + #endif 173 178 } 174 179 175 180 /** ··· 327 322 { 328 323 struct cred *new; 329 324 int ret; 325 + 326 + #ifdef CONFIG_KEYS_REQUEST_CACHE 327 + p->cached_requested_key = NULL; 328 + #endif 330 329 331 330 if ( 332 331 #ifdef CONFIG_KEYS
+18
security/keys/Kconfig
··· 25 25 def_bool y 26 26 depends on COMPAT && KEYS 27 27 28 + config 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 + 28 46 config PERSISTENT_KEYRINGS 29 47 bool "Enable register of persistent per-UID keyrings" 30 48 depends on KEYS
+3 -3
security/keys/internal.h
··· 135 135 136 136 extern bool key_default_cmp(const struct key *key, 137 137 const struct key_match_data *match_data); 138 - extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 138 + extern key_ref_t keyring_search_rcu(key_ref_t keyring_ref, 139 139 struct keyring_search_context *ctx); 140 140 141 - extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); 142 - extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); 141 + extern key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx); 142 + extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx); 143 143 144 144 extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); 145 145
+2 -2
security/keys/key.c
··· 455 455 456 456 /* disable the authorisation key */ 457 457 if (authkey) 458 - key_revoke(authkey); 458 + key_invalidate(authkey); 459 459 460 460 if (prep->expiry != TIME64_MAX) { 461 461 key->expiry = prep->expiry; ··· 612 612 613 613 /* disable the authorisation key */ 614 614 if (authkey) 615 - key_revoke(authkey); 615 + key_invalidate(authkey); 616 616 } 617 617 618 618 mutex_unlock(&key_construction_mutex);
+9 -7
security/keys/keyring.c
··· 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 835 * @keyring_ref: A pointer to the keyring with possession indicator. 836 836 * @ctx: The keyring search context. 837 837 * ··· 843 843 * addition, the LSM gets to forbid keyring searches and key matches. 844 844 * 845 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 850 * Keys are matched to the type provided and are then filtered by the match 849 851 * function, which is given the description to use in any way it sees fit. The ··· 864 862 * In the case of a successful return, the possession attribute from 865 863 * @keyring_ref is propagated to the returned key reference. 866 864 */ 867 - key_ref_t keyring_search_aux(key_ref_t keyring_ref, 865 + key_ref_t keyring_search_rcu(key_ref_t keyring_ref, 868 866 struct keyring_search_context *ctx) 869 867 { 870 868 struct key *keyring; ··· 886 884 return ERR_PTR(err); 887 885 } 888 886 889 - rcu_read_lock(); 890 887 ctx->now = ktime_get_real_seconds(); 891 888 if (search_nested_keyrings(keyring, ctx)) 892 889 __key_get(key_ref_to_ptr(ctx->result)); 893 - rcu_read_unlock(); 894 890 return ctx->result; 895 891 } 896 892 ··· 898 898 * @type: The type of keyring we want to find. 899 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 902 * type's default matching function and preferred search method. 903 903 */ 904 904 key_ref_t keyring_search(key_ref_t keyring, ··· 924 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 931 if (type->match_free) 930 932 type->match_free(&ctx.match_data);
+3 -1
security/keys/proc.c
··· 175 175 * skip if the key does not indicate the possessor can view it 176 176 */ 177 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 181 if (!IS_ERR(skey_ref)) { 180 182 key_ref_put(skey_ref); 181 183 key_ref = make_key_ref(key, 1);
+18 -23
security/keys/process_keys.c
··· 314 314 315 315 /* 316 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 320 * The search criteria are the type and the match function. The description is 320 321 * given to the match function as a parameter, but doesn't otherwise influence ··· 334 333 * In the case of a successful return, the possession attribute is set on the 335 334 * returned key reference. 336 335 */ 337 - key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx) 336 + key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx) 338 337 { 339 338 key_ref_t key_ref, ret, err; 340 339 const struct cred *cred = ctx->cred; ··· 352 351 353 352 /* search the thread keyring first */ 354 353 if (cred->thread_keyring) { 355 - key_ref = keyring_search_aux( 354 + key_ref = keyring_search_rcu( 356 355 make_key_ref(cred->thread_keyring, 1), ctx); 357 356 if (!IS_ERR(key_ref)) 358 357 goto found; ··· 370 369 371 370 /* search the process keyring second */ 372 371 if (cred->process_keyring) { 373 - key_ref = keyring_search_aux( 372 + key_ref = keyring_search_rcu( 374 373 make_key_ref(cred->process_keyring, 1), ctx); 375 374 if (!IS_ERR(key_ref)) 376 375 goto found; ··· 391 390 392 391 /* search the session keyring */ 393 392 if (cred->session_keyring) { 394 - key_ref = keyring_search_aux( 393 + key_ref = keyring_search_rcu( 395 394 make_key_ref(cred->session_keyring, 1), ctx); 396 395 397 396 if (!IS_ERR(key_ref)) ··· 412 411 } 413 412 /* or search the user-session keyring */ 414 413 else if (READ_ONCE(cred->user->session_keyring)) { 415 - key_ref = keyring_search_aux( 414 + key_ref = keyring_search_rcu( 416 415 make_key_ref(READ_ONCE(cred->user->session_keyring), 1), 417 416 ctx); 418 417 if (!IS_ERR(key_ref)) ··· 445 444 * the keys attached to the assumed authorisation key using its credentials if 446 445 * one is available. 447 446 * 448 - * Return same as search_my_process_keyrings(). 447 + * The caller must be holding the RCU read lock. 448 + * 449 + * Return same as search_cred_keyrings_rcu(). 449 450 */ 450 - key_ref_t search_process_keyrings(struct keyring_search_context *ctx) 451 + key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx) 451 452 { 452 453 struct request_key_auth *rka; 453 454 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; 454 455 455 - might_sleep(); 456 - 457 - key_ref = search_my_process_keyrings(ctx); 456 + key_ref = search_cred_keyrings_rcu(ctx); 458 457 if (!IS_ERR(key_ref)) 459 458 goto found; 460 459 err = key_ref; ··· 469 468 ) { 470 469 const struct cred *cred = ctx->cred; 471 470 472 - /* defend against the auth key being revoked */ 473 - down_read(&cred->request_key_auth->sem); 474 - 475 - if (key_validate(ctx->cred->request_key_auth) == 0) { 471 + if (key_validate(cred->request_key_auth) == 0) { 476 472 rka = ctx->cred->request_key_auth->payload.data[0]; 477 473 474 + //// was search_process_keyrings() [ie. recursive] 478 475 ctx->cred = rka->cred; 479 - key_ref = search_process_keyrings(ctx); 476 + key_ref = search_cred_keyrings_rcu(ctx); 480 477 ctx->cred = cred; 481 - 482 - up_read(&cred->request_key_auth->sem); 483 478 484 479 if (!IS_ERR(key_ref)) 485 480 goto found; 486 - 487 481 ret = key_ref; 488 - } else { 489 - up_read(&cred->request_key_auth->sem); 490 482 } 491 483 } 492 484 ··· 494 500 found: 495 501 return key_ref; 496 502 } 497 - 498 503 /* 499 504 * See if the key we're looking at is the target key. 500 505 */ ··· 680 687 ctx.index_key = key->index_key; 681 688 ctx.match_data.raw_data = key; 682 689 kdebug("check possessed"); 683 - skey_ref = search_process_keyrings(&ctx); 690 + rcu_read_lock(); 691 + skey_ref = search_process_keyrings_rcu(&ctx); 692 + rcu_read_unlock(); 684 693 kdebug("possessed=%p", skey_ref); 685 694 686 695 if (!IS_ERR(skey_ref)) {
+91 -46
security/keys/request_key.c
··· 18 18 19 19 #define key_negative_timeout 60 /* default timeout on a negative key's existence */ 20 20 21 + static 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 + 35 + static 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 47 * complete_request_key - Complete the construction of a key. 23 48 * @authkey: The authorisation key. ··· 243 218 /* check that the actor called complete_request_key() prior to 244 219 * returning an error */ 245 220 WARN_ON(ret < 0 && 246 - !test_bit(KEY_FLAG_REVOKED, &authkey->flags)); 221 + !test_bit(KEY_FLAG_INVALIDATED, &authkey->flags)); 247 222 248 223 key_put(authkey); 249 224 kleave(" = %d", ret); ··· 406 381 * waited for locks */ 407 382 mutex_lock(&key_construction_mutex); 408 383 409 - key_ref = search_process_keyrings(ctx); 384 + rcu_read_lock(); 385 + key_ref = search_process_keyrings_rcu(ctx); 386 + rcu_read_unlock(); 410 387 if (!IS_ERR(key_ref)) 411 388 goto key_already_present; 412 389 ··· 583 556 } 584 557 } 585 558 559 + key = check_cached_key(&ctx); 560 + if (key) 561 + return key; 562 + 586 563 /* search all the process keyrings for a key */ 587 - key_ref = search_process_keyrings(&ctx); 564 + rcu_read_lock(); 565 + key_ref = search_process_keyrings_rcu(&ctx); 566 + rcu_read_unlock(); 588 567 589 568 if (!IS_ERR(key_ref)) { 569 + if (dest_keyring) { 570 + ret = key_task_permission(key_ref, current_cred(), 571 + KEY_NEED_LINK); 572 + if (ret < 0) { 573 + key_ref_put(key_ref); 574 + key = ERR_PTR(ret); 575 + goto error_free; 576 + } 577 + } 578 + 590 579 key = key_ref_to_ptr(key_ref); 591 580 if (dest_keyring) { 592 581 ret = key_link(dest_keyring, key); ··· 612 569 goto error_free; 613 570 } 614 571 } 572 + 573 + /* Only cache the key on immediate success */ 574 + cache_requested_key(key); 615 575 } else if (PTR_ERR(key_ref) != -EAGAIN) { 616 576 key = ERR_CAST(key_ref); 617 577 } else { ··· 735 689 } 736 690 EXPORT_SYMBOL(request_key_with_auxdata); 737 691 738 - /* 739 - * request_key_async - Request a key (allow async construction) 740 - * @type: Type of key. 741 - * @description: The searchable description of the key. 742 - * @callout_info: The data to pass to the instantiation upcall (or NULL). 743 - * @callout_len: The length of callout_info. 692 + /** 693 + * request_key_rcu - Request key from RCU-read-locked context 694 + * @type: The type of key we want. 695 + * @description: The name of the key we want. 744 696 * 745 - * As for request_key_and_link() except that it does not add the returned key 746 - * to a keyring if found, new keys are always allocated in the user's quota and 747 - * no auxiliary data can be passed. 697 + * Request a key from a context that we may not sleep in (such as RCU-mode 698 + * pathwalk). Keys under construction are ignored. 748 699 * 749 - * The caller should call wait_for_key_construction() to wait for the 750 - * completion of the returned key if it is still undergoing construction. 700 + * Return a pointer to the found key if successful, -ENOKEY if we couldn't find 701 + * a key or some other error if the key found was unsuitable or inaccessible. 751 702 */ 752 - struct key *request_key_async(struct key_type *type, 753 - const char *description, 754 - const void *callout_info, 755 - size_t callout_len) 703 + struct key *request_key_rcu(struct key_type *type, const char *description) 756 704 { 757 - return request_key_and_link(type, description, callout_info, 758 - callout_len, NULL, NULL, 759 - KEY_ALLOC_IN_QUOTA); 760 - } 761 - EXPORT_SYMBOL(request_key_async); 705 + struct keyring_search_context ctx = { 706 + .index_key.type = type, 707 + .index_key.description = description, 708 + .index_key.desc_len = strlen(description), 709 + .cred = current_cred(), 710 + .match_data.cmp = key_default_cmp, 711 + .match_data.raw_data = description, 712 + .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 713 + .flags = (KEYRING_SEARCH_DO_STATE_CHECK | 714 + KEYRING_SEARCH_SKIP_EXPIRED), 715 + }; 716 + struct key *key; 717 + key_ref_t key_ref; 762 718 763 - /* 764 - * request a key with auxiliary data for the upcaller (allow async construction) 765 - * @type: Type of key. 766 - * @description: The searchable description of the key. 767 - * @callout_info: The data to pass to the instantiation upcall (or NULL). 768 - * @callout_len: The length of callout_info. 769 - * @aux: Auxiliary data for the upcall. 770 - * 771 - * As for request_key_and_link() except that it does not add the returned key 772 - * to a keyring if found and new keys are always allocated in the user's quota. 773 - * 774 - * The caller should call wait_for_key_construction() to wait for the 775 - * completion of the returned key if it is still undergoing construction. 776 - */ 777 - struct key *request_key_async_with_auxdata(struct key_type *type, 778 - const char *description, 779 - const void *callout_info, 780 - size_t callout_len, 781 - void *aux) 782 - { 783 - return request_key_and_link(type, description, callout_info, 784 - callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA); 719 + kenter("%s,%s", type->name, description); 720 + 721 + key = check_cached_key(&ctx); 722 + if (key) 723 + return key; 724 + 725 + /* search all the process keyrings for a key */ 726 + key_ref = search_process_keyrings_rcu(&ctx); 727 + if (IS_ERR(key_ref)) { 728 + key = ERR_CAST(key_ref); 729 + if (PTR_ERR(key_ref) == -EAGAIN) 730 + key = ERR_PTR(-ENOKEY); 731 + } else { 732 + key = key_ref_to_ptr(key_ref); 733 + cache_requested_key(key); 734 + } 735 + 736 + kleave(" = %p", key); 737 + return key; 785 738 } 786 - EXPORT_SYMBOL(request_key_async_with_auxdata); 739 + EXPORT_SYMBOL(request_key_rcu);
+36 -24
security/keys/request_key_auth.c
··· 54 54 static int request_key_auth_instantiate(struct key *key, 55 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 58 return 0; 59 59 } 60 60 ··· 64 64 static void request_key_auth_describe(const struct key *key, 65 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 69 seq_puts(m, "key:"); 70 70 seq_puts(m, key->description); ··· 79 79 static long request_key_auth_read(const struct key *key, 80 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 83 size_t datalen; 84 84 long ret; 85 85 ··· 98 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 - */ 106 - static 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 - 118 101 static void free_request_key_auth(struct request_key_auth *rka) 119 102 { 120 103 if (!rka) ··· 111 128 } 112 129 113 130 /* 131 + * Dispose of the request_key_auth record under RCU conditions 132 + */ 133 + static void request_key_auth_rcu_disposal(struct rcu_head *rcu) 134 + { 135 + struct request_key_auth *rka = 136 + container_of(rcu, struct request_key_auth, rcu); 137 + 138 + free_request_key_auth(rka); 139 + } 140 + 141 + /* 142 + * Handle revocation of an authorisation token key. 143 + * 144 + * Called with the key sem write-locked. 145 + */ 146 + static void request_key_auth_revoke(struct key *key) 147 + { 148 + struct request_key_auth *rka = dereference_key_locked(key); 149 + 150 + kenter("{%d}", key->serial); 151 + rcu_assign_keypointer(key, NULL); 152 + call_rcu(&rka->rcu, request_key_auth_rcu_disposal); 153 + } 154 + 155 + /* 114 156 * Destroy an instantiation authorisation token key. 115 157 */ 116 158 static void request_key_auth_destroy(struct key *key) 117 159 { 118 - struct request_key_auth *rka = get_request_key_auth(key); 160 + struct request_key_auth *rka = rcu_access_pointer(key->payload.rcu_data0); 119 161 120 162 kenter("{%d}", key->serial); 121 - 122 - free_request_key_auth(rka); 163 + if (rka) { 164 + rcu_assign_keypointer(key, NULL); 165 + call_rcu(&rka->rcu, request_key_auth_rcu_disposal); 166 + } 123 167 } 124 168 125 169 /* ··· 255 245 256 246 ctx.index_key.desc_len = sprintf(description, "%x", target_id); 257 247 258 - authkey_ref = search_process_keyrings(&ctx); 248 + rcu_read_lock(); 249 + authkey_ref = search_process_keyrings_rcu(&ctx); 250 + rcu_read_unlock(); 259 251 260 252 if (IS_ERR(authkey_ref)) { 261 253 authkey = ERR_CAST(authkey_ref);