summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--Documentation/security/keys/core.rst38
-rw-r--r--Documentation/security/keys/request-key.rst33
-rw-r--r--include/keys/request_key_auth-type.h1
-rw-r--r--include/linux/key.h14
-rw-r--r--include/linux/sched.h5
-rw-r--r--include/linux/tracehook.h7
-rw-r--r--kernel/cred.c9
-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
15 files changed, 229 insertions, 164 deletions
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index 823d29bf44f7..a0e245f9576f 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -433,6 +433,10 @@ The main syscalls are:
433 /sbin/request-key will be invoked in an attempt to obtain a key. The 433 /sbin/request-key will be invoked in an attempt to obtain a key. The
434 callout_info string will be passed as an argument to the program. 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 See also Documentation/security/keys/request-key.rst. 440 See also Documentation/security/keys/request-key.rst.
437 441
438 442
@@ -1111,36 +1115,14 @@ payload contents" for more information.
1111 is a blob of length callout_len, if given (the length may be 0). 1115 is a blob of length callout_len, if given (the length may be 0).
1112 1116
1113 1117
1114 * A key can be requested asynchronously by calling one of:: 1118 * To search for a key under RCU conditions, call::
1115
1116 struct key *request_key_async(const struct key_type *type,
1117 const char *description,
1118 const void *callout_info,
1119 size_t callout_len);
1120
1121 or::
1122
1123 struct key *request_key_async_with_auxdata(const struct key_type *type,
1124 const char *description,
1125 const char *callout_info,
1126 size_t callout_len,
1127 void *aux);
1128
1129 which are asynchronous equivalents of request_key() and
1130 request_key_with_auxdata() respectively.
1131
1132 These two functions return with the key potentially still under
1133 construction. To wait for construction completion, the following should be
1134 called::
1135
1136 int wait_for_key_construction(struct key *key, bool intr);
1137 1119
1138 The function will wait for the key to finish being constructed and then 1120 struct key *request_key_rcu(const struct key_type *type,
1139 invokes key_validate() to return an appropriate value to indicate the state 1121 const char *description);
1140 of the key (0 indicates the key is usable).
1141 1122
1142 If intr is true, then the wait can be interrupted by a signal, in which 1123 which is similar to request_key() except that it does not check for keys
1143 case error ERESTARTSYS will be returned. 1124 that are under construction and it will not call out to userspace to
1125 construct a key if it can't find a match.
1144 1126
1145 1127
1146 * When it is no longer required, the key should be released using:: 1128 * When it is no longer required, the key should be released using::
diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst
index 600ad67d1707..5a210baa583a 100644
--- a/Documentation/security/keys/request-key.rst
+++ b/Documentation/security/keys/request-key.rst
@@ -23,18 +23,8 @@ or::
23 23
24or:: 24or::
25 25
26 struct key *request_key_async(const struct key_type *type, 26 struct key *request_key_rcu(const struct key_type *type,
27 const char *description, 27 const char *description);
28 const char *callout_info,
29 size_t callout_len);
30
31or::
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);
38 28
39Or by userspace invoking the request_key system call:: 29Or by userspace invoking the request_key system call::
40 30
@@ -48,14 +38,14 @@ does not need to link the key to a keyring to prevent it from being immediately
48destroyed. The kernel interface returns a pointer directly to the key, and 38destroyed. The kernel interface returns a pointer directly to the key, and
49it's up to the caller to destroy the key. 39it's up to the caller to destroy the key.
50 40
51The request_key*_with_auxdata() calls are like the in-kernel request_key*() 41The request_key_with_auxdata() calls is like the in-kernel request_key() call,
52calls, except that they permit auxiliary data to be passed to the upcaller (the 42except that they permit auxiliary data to be passed to the upcaller (the
53default is NULL). This is only useful for those key types that define their 43default is NULL). This is only useful for those key types that define their
54own upcall mechanism rather than using /sbin/request-key. 44own upcall mechanism rather than using /sbin/request-key.
55 45
56The two async in-kernel calls may return keys that are still in the process of 46The request_key_rcu() call is like the in-kernel request_key() call, except
57being constructed. The two non-async ones will wait for construction to 47that it doesn't check for keys that are under construction and doesn't attempt
58complete first. 48to construct missing keys.
59 49
60The userspace interface links the key to a keyring associated with the process 50The userspace interface links the key to a keyring associated with the process
61to prevent the key from going away, and returns the serial number of the key to 51to prevent the key from going away, and returns the serial number of the key to
@@ -148,7 +138,7 @@ The Search Algorithm
148 138
149A search of any particular keyring proceeds in the following fashion: 139A search of any particular keyring proceeds in the following fashion:
150 140
151 1) When the key management code searches for a key (keyring_search_aux) it 141 1) When the key management code searches for a key (keyring_search_rcu) it
152 firstly calls key_permission(SEARCH) on the keyring it's starting with, 142 firstly calls key_permission(SEARCH) on the keyring it's starting with,
153 if this denies permission, it doesn't search further. 143 if this denies permission, it doesn't search further.
154 144
@@ -167,6 +157,9 @@ The process stops immediately a valid key is found with permission granted to
167use it. Any error from a previous match attempt is discarded and the key is 157use it. Any error from a previous match attempt is discarded and the key is
168returned. 158returned.
169 159
160When request_key() is invoked, if CONFIG_KEYS_REQUEST_CACHE=y, a per-task
161one-key cache is first checked for a match.
162
170When search_process_keyrings() is invoked, it performs the following searches 163When search_process_keyrings() is invoked, it performs the following searches
171until one succeeds: 164until one succeeds:
172 165
@@ -186,7 +179,9 @@ until one succeeds:
186 c) The calling process's session keyring is searched. 179 c) The calling process's session keyring is searched.
187 180
188The moment one succeeds, all pending errors are discarded and the found key is 181The moment one succeeds, all pending errors are discarded and the found key is
189returned. 182returned. If CONFIG_KEYS_REQUEST_CACHE=y, then that key is placed in the
183per-task cache, displacing the previous key. The cache is cleared on exit or
184just prior to resumption of userspace.
190 185
191Only if all these fail does the whole thing fail with the highest priority 186Only if all these fail does the whole thing fail with the highest priority
192error. Note that several errors may have come from LSM. 187error. Note that several errors may have come from LSM.
diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h
index 20485ca481f4..36b89a933310 100644
--- a/include/keys/request_key_auth-type.h
+++ b/include/keys/request_key_auth-type.h
@@ -14,6 +14,7 @@
14 * Authorisation record for request_key(). 14 * Authorisation record for request_key().
15 */ 15 */
16struct request_key_auth { 16struct request_key_auth {
17 struct rcu_head rcu;
17 struct key *target_key; 18 struct key *target_key;
18 struct key *dest_keyring; 19 struct key *dest_keyring;
19 const struct cred *cred; 20 const struct cred *cred;
diff --git a/include/linux/key.h b/include/linux/key.h
index 8b297b94bfb3..ad17c8f30b4c 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -269,23 +269,15 @@ extern struct key *request_key(struct key_type *type,
269 const char *description, 269 const char *description,
270 const char *callout_info); 270 const char *callout_info);
271 271
272extern struct key *request_key_rcu(struct key_type *type,
273 const char *description);
274
272extern struct key *request_key_with_auxdata(struct key_type *type, 275extern struct key *request_key_with_auxdata(struct key_type *type,
273 const char *description, 276 const char *description,
274 const void *callout_info, 277 const void *callout_info,
275 size_t callout_len, 278 size_t callout_len,
276 void *aux); 279 void *aux);
277 280
278extern struct key *request_key_async(struct key_type *type,
279 const char *description,
280 const void *callout_info,
281 size_t callout_len);
282
283extern 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
289extern int wait_for_key_construction(struct key *key, bool intr); 281extern int wait_for_key_construction(struct key *key, bool intr);
290 282
291extern int key_validate(const struct key *key); 283extern int key_validate(const struct key *key);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 459d95e4a574..8dc1811487f5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -892,6 +892,11 @@ struct task_struct {
892 /* Effective (overridable) subjective task credentials (COW): */ 892 /* Effective (overridable) subjective task credentials (COW): */
893 const struct cred __rcu *cred; 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 * executable name, excluding path. 901 * executable name, excluding path.
897 * 902 *
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 09d678433fc0..8446573cc682 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -184,6 +184,13 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
184 if (unlikely(current->task_works)) 184 if (unlikely(current->task_works))
185 task_work_run(); 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 mem_cgroup_handle_over_high(); 194 mem_cgroup_handle_over_high();
188 blkcg_maybe_throttle_current(); 195 blkcg_maybe_throttle_current();
189} 196}
diff --git a/kernel/cred.c b/kernel/cred.c
index 12a656217a70..f9a0ce66c9c3 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -170,6 +170,11 @@ void exit_creds(struct task_struct *tsk)
170 validate_creds(cred); 170 validate_creds(cred);
171 alter_cred_subscribers(cred, -1); 171 alter_cred_subscribers(cred, -1);
172 put_cred(cred); 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/**
@@ -323,6 +328,10 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
323 struct cred *new; 328 struct cred *new;
324 int ret; 329 int ret;
325 330
331#ifdef CONFIG_KEYS_REQUEST_CACHE
332 p->cached_requested_key = NULL;
333#endif
334
326 if ( 335 if (
327#ifdef CONFIG_KEYS 336#ifdef CONFIG_KEYS
328 !p->cred->thread_keyring && 337 !p->cred->thread_keyring &&
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);