aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-24 05:35:15 -0400
committerDavid Howells <dhowells@redhat.com>2013-09-24 05:35:15 -0400
commit4bdf0bc300314141e5475e145acb8b5ad846f00d (patch)
treeecf5a1d74d507410a9defa32edb4ea73edb9d205
parent16feef4340172b7dbb9cba60850e78fa6388adf1 (diff)
KEYS: Introduce a search context structure
Search functions pass around a bunch of arguments, each of which gets copied with each call. Introduce a search context structure to hold these. Whilst we're at it, create a search flag that indicates whether the search should be directly to the description or whether it should iterate through all keys looking for a non-description match. This will be useful when keyrings use a generic data struct with generic routines to manage their content as the search terms can just be passed through to the iterator callback function. Also, for future use, the data to be supplied to the match function is separated from the description pointer in the search context. This makes it clear which is being supplied. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--include/linux/key-type.h5
-rw-r--r--security/keys/internal.h40
-rw-r--r--security/keys/keyring.c70
-rw-r--r--security/keys/proc.c17
-rw-r--r--security/keys/process_keys.c117
-rw-r--r--security/keys/request_key.c56
-rw-r--r--security/keys/request_key_auth.c14
-rw-r--r--security/keys/user_defined.c18
8 files changed, 179 insertions, 158 deletions
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 518a53afb9ea..f58737bcb050 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -63,6 +63,11 @@ struct key_type {
63 */ 63 */
64 size_t def_datalen; 64 size_t def_datalen;
65 65
66 /* Default key search algorithm. */
67 unsigned def_lookup_type;
68#define KEYRING_SEARCH_LOOKUP_DIRECT 0x0000 /* Direct lookup by description. */
69#define KEYRING_SEARCH_LOOKUP_ITERATE 0x0001 /* Iterative search. */
70
66 /* vet a description */ 71 /* vet a description */
67 int (*vet_description)(const char *description); 72 int (*vet_description)(const char *description);
68 73
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 77441dd1f9d4..f4bf938b68b4 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -107,23 +107,31 @@ extern struct key *keyring_search_instkey(struct key *keyring,
107 107
108typedef int (*key_match_func_t)(const struct key *, const void *); 108typedef int (*key_match_func_t)(const struct key *, const void *);
109 109
110struct keyring_search_context {
111 struct keyring_index_key index_key;
112 const struct cred *cred;
113 key_match_func_t match;
114 const void *match_data;
115 unsigned flags;
116#define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */
117#define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */
118#define KEYRING_SEARCH_DO_STATE_CHECK 0x0004 /* Override NO_STATE_CHECK */
119#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0008 /* Don't update times */
120#define KEYRING_SEARCH_NO_CHECK_PERM 0x0010 /* Don't check permissions */
121#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0020 /* Give an error on excessive depth */
122
123 /* Internal stuff */
124 int skipped_ret;
125 bool possessed;
126 key_ref_t result;
127 struct timespec now;
128};
129
110extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 130extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
111 const struct cred *cred, 131 struct keyring_search_context *ctx);
112 struct key_type *type, 132
113 const void *description, 133extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
114 key_match_func_t match, 134extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
115 bool no_state_check);
116
117extern key_ref_t search_my_process_keyrings(struct key_type *type,
118 const void *description,
119 key_match_func_t match,
120 bool no_state_check,
121 const struct cred *cred);
122extern key_ref_t search_process_keyrings(struct key_type *type,
123 const void *description,
124 key_match_func_t match,
125 bool no_state_check,
126 const struct cred *cred);
127 135
128extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); 136extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
129 137
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index c7f59f9dd7b6..b42f2d4f7f83 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -280,11 +280,7 @@ EXPORT_SYMBOL(keyring_alloc);
280/** 280/**
281 * keyring_search_aux - Search a keyring tree for a key matching some criteria 281 * keyring_search_aux - Search a keyring tree for a key matching some criteria
282 * @keyring_ref: A pointer to the keyring with possession indicator. 282 * @keyring_ref: A pointer to the keyring with possession indicator.
283 * @cred: The credentials to use for permissions checks. 283 * @ctx: The keyring search context.
284 * @type: The type of key to search for.
285 * @description: Parameter for @match.
286 * @match: Function to rule on whether or not a key is the one required.
287 * @no_state_check: Don't check if a matching key is bad
288 * 284 *
289 * Search the supplied keyring tree for a key that matches the criteria given. 285 * Search the supplied keyring tree for a key that matches the criteria given.
290 * The root keyring and any linked keyrings must grant Search permission to the 286 * The root keyring and any linked keyrings must grant Search permission to the
@@ -314,11 +310,7 @@ EXPORT_SYMBOL(keyring_alloc);
314 * @keyring_ref is propagated to the returned key reference. 310 * @keyring_ref is propagated to the returned key reference.
315 */ 311 */
316key_ref_t keyring_search_aux(key_ref_t keyring_ref, 312key_ref_t keyring_search_aux(key_ref_t keyring_ref,
317 const struct cred *cred, 313 struct keyring_search_context *ctx)
318 struct key_type *type,
319 const void *description,
320 key_match_func_t match,
321 bool no_state_check)
322{ 314{
323 struct { 315 struct {
324 /* Need a separate keylist pointer for RCU purposes */ 316 /* Need a separate keylist pointer for RCU purposes */
@@ -328,20 +320,18 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
328 } stack[KEYRING_SEARCH_MAX_DEPTH]; 320 } stack[KEYRING_SEARCH_MAX_DEPTH];
329 321
330 struct keyring_list *keylist; 322 struct keyring_list *keylist;
331 struct timespec now;
332 unsigned long kflags; 323 unsigned long kflags;
333 struct key *keyring, *key; 324 struct key *keyring, *key;
334 key_ref_t key_ref; 325 key_ref_t key_ref;
335 bool possessed;
336 long err; 326 long err;
337 int sp, nkeys, kix; 327 int sp, nkeys, kix;
338 328
339 keyring = key_ref_to_ptr(keyring_ref); 329 keyring = key_ref_to_ptr(keyring_ref);
340 possessed = is_key_possessed(keyring_ref); 330 ctx->possessed = is_key_possessed(keyring_ref);
341 key_check(keyring); 331 key_check(keyring);
342 332
343 /* top keyring must have search permission to begin the search */ 333 /* top keyring must have search permission to begin the search */
344 err = key_task_permission(keyring_ref, cred, KEY_SEARCH); 334 err = key_task_permission(keyring_ref, ctx->cred, KEY_SEARCH);
345 if (err < 0) { 335 if (err < 0) {
346 key_ref = ERR_PTR(err); 336 key_ref = ERR_PTR(err);
347 goto error; 337 goto error;
@@ -353,7 +343,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
353 343
354 rcu_read_lock(); 344 rcu_read_lock();
355 345
356 now = current_kernel_time(); 346 ctx->now = current_kernel_time();
357 err = -EAGAIN; 347 err = -EAGAIN;
358 sp = 0; 348 sp = 0;
359 349
@@ -361,16 +351,17 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
361 * are looking for */ 351 * are looking for */
362 key_ref = ERR_PTR(-EAGAIN); 352 key_ref = ERR_PTR(-EAGAIN);
363 kflags = keyring->flags; 353 kflags = keyring->flags;
364 if (keyring->type == type && match(keyring, description)) { 354 if (keyring->type == ctx->index_key.type &&
355 ctx->match(keyring, ctx->match_data)) {
365 key = keyring; 356 key = keyring;
366 if (no_state_check) 357 if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK)
367 goto found; 358 goto found;
368 359
369 /* check it isn't negative and hasn't expired or been 360 /* check it isn't negative and hasn't expired or been
370 * revoked */ 361 * revoked */
371 if (kflags & (1 << KEY_FLAG_REVOKED)) 362 if (kflags & (1 << KEY_FLAG_REVOKED))
372 goto error_2; 363 goto error_2;
373 if (key->expiry && now.tv_sec >= key->expiry) 364 if (key->expiry && ctx->now.tv_sec >= key->expiry)
374 goto error_2; 365 goto error_2;
375 key_ref = ERR_PTR(key->type_data.reject_error); 366 key_ref = ERR_PTR(key->type_data.reject_error);
376 if (kflags & (1 << KEY_FLAG_NEGATIVE)) 367 if (kflags & (1 << KEY_FLAG_NEGATIVE))
@@ -384,7 +375,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
384 if (kflags & ((1 << KEY_FLAG_INVALIDATED) | 375 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
385 (1 << KEY_FLAG_REVOKED) | 376 (1 << KEY_FLAG_REVOKED) |
386 (1 << KEY_FLAG_NEGATIVE)) || 377 (1 << KEY_FLAG_NEGATIVE)) ||
387 (keyring->expiry && now.tv_sec >= keyring->expiry)) 378 (keyring->expiry && ctx->now.tv_sec >= keyring->expiry))
388 goto error_2; 379 goto error_2;
389 380
390 /* start processing a new keyring */ 381 /* start processing a new keyring */
@@ -406,29 +397,29 @@ descend:
406 kflags = key->flags; 397 kflags = key->flags;
407 398
408 /* ignore keys not of this type */ 399 /* ignore keys not of this type */
409 if (key->type != type) 400 if (key->type != ctx->index_key.type)
410 continue; 401 continue;
411 402
412 /* skip invalidated, revoked and expired keys */ 403 /* skip invalidated, revoked and expired keys */
413 if (!no_state_check) { 404 if (!(ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK)) {
414 if (kflags & ((1 << KEY_FLAG_INVALIDATED) | 405 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
415 (1 << KEY_FLAG_REVOKED))) 406 (1 << KEY_FLAG_REVOKED)))
416 continue; 407 continue;
417 408
418 if (key->expiry && now.tv_sec >= key->expiry) 409 if (key->expiry && ctx->now.tv_sec >= key->expiry)
419 continue; 410 continue;
420 } 411 }
421 412
422 /* keys that don't match */ 413 /* keys that don't match */
423 if (!match(key, description)) 414 if (!ctx->match(key, ctx->match_data))
424 continue; 415 continue;
425 416
426 /* key must have search permissions */ 417 /* key must have search permissions */
427 if (key_task_permission(make_key_ref(key, possessed), 418 if (key_task_permission(make_key_ref(key, ctx->possessed),
428 cred, KEY_SEARCH) < 0) 419 ctx->cred, KEY_SEARCH) < 0)
429 continue; 420 continue;
430 421
431 if (no_state_check) 422 if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK)
432 goto found; 423 goto found;
433 424
434 /* we set a different error code if we pass a negative key */ 425 /* we set a different error code if we pass a negative key */
@@ -456,8 +447,8 @@ ascend:
456 if (sp >= KEYRING_SEARCH_MAX_DEPTH) 447 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
457 continue; 448 continue;
458 449
459 if (key_task_permission(make_key_ref(key, possessed), 450 if (key_task_permission(make_key_ref(key, ctx->possessed),
460 cred, KEY_SEARCH) < 0) 451 ctx->cred, KEY_SEARCH) < 0)
461 continue; 452 continue;
462 453
463 /* stack the current position */ 454 /* stack the current position */
@@ -489,12 +480,12 @@ not_this_keyring:
489 /* we found a viable match */ 480 /* we found a viable match */
490found: 481found:
491 atomic_inc(&key->usage); 482 atomic_inc(&key->usage);
492 key->last_used_at = now.tv_sec; 483 key->last_used_at = ctx->now.tv_sec;
493 keyring->last_used_at = now.tv_sec; 484 keyring->last_used_at = ctx->now.tv_sec;
494 while (sp > 0) 485 while (sp > 0)
495 stack[--sp].keyring->last_used_at = now.tv_sec; 486 stack[--sp].keyring->last_used_at = ctx->now.tv_sec;
496 key_check(key); 487 key_check(key);
497 key_ref = make_key_ref(key, possessed); 488 key_ref = make_key_ref(key, ctx->possessed);
498error_2: 489error_2:
499 rcu_read_unlock(); 490 rcu_read_unlock();
500error: 491error:
@@ -514,11 +505,20 @@ key_ref_t keyring_search(key_ref_t keyring,
514 struct key_type *type, 505 struct key_type *type,
515 const char *description) 506 const char *description)
516{ 507{
517 if (!type->match) 508 struct keyring_search_context ctx = {
509 .index_key.type = type,
510 .index_key.description = description,
511 .cred = current_cred(),
512 .match = type->match,
513 .match_data = description,
514 .flags = (type->def_lookup_type |
515 KEYRING_SEARCH_DO_STATE_CHECK),
516 };
517
518 if (!ctx.match)
518 return ERR_PTR(-ENOKEY); 519 return ERR_PTR(-ENOKEY);
519 520
520 return keyring_search_aux(keyring, current->cred, 521 return keyring_search_aux(keyring, &ctx);
521 type, description, type->match, false);
522} 522}
523EXPORT_SYMBOL(keyring_search); 523EXPORT_SYMBOL(keyring_search);
524 524
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 217b6855e815..88e9a466940f 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -182,7 +182,6 @@ static void proc_keys_stop(struct seq_file *p, void *v)
182 182
183static int proc_keys_show(struct seq_file *m, void *v) 183static int proc_keys_show(struct seq_file *m, void *v)
184{ 184{
185 const struct cred *cred = current_cred();
186 struct rb_node *_p = v; 185 struct rb_node *_p = v;
187 struct key *key = rb_entry(_p, struct key, serial_node); 186 struct key *key = rb_entry(_p, struct key, serial_node);
188 struct timespec now; 187 struct timespec now;
@@ -191,15 +190,23 @@ static int proc_keys_show(struct seq_file *m, void *v)
191 char xbuf[12]; 190 char xbuf[12];
192 int rc; 191 int rc;
193 192
193 struct keyring_search_context ctx = {
194 .index_key.type = key->type,
195 .index_key.description = key->description,
196 .cred = current_cred(),
197 .match = lookup_user_key_possessed,
198 .match_data = key,
199 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
200 KEYRING_SEARCH_LOOKUP_DIRECT),
201 };
202
194 key_ref = make_key_ref(key, 0); 203 key_ref = make_key_ref(key, 0);
195 204
196 /* determine if the key is possessed by this process (a test we can 205 /* determine if the key is possessed by this process (a test we can
197 * skip if the key does not indicate the possessor can view it 206 * skip if the key does not indicate the possessor can view it
198 */ 207 */
199 if (key->perm & KEY_POS_VIEW) { 208 if (key->perm & KEY_POS_VIEW) {
200 skey_ref = search_my_process_keyrings(key->type, key, 209 skey_ref = search_my_process_keyrings(&ctx);
201 lookup_user_key_possessed,
202 true, cred);
203 if (!IS_ERR(skey_ref)) { 210 if (!IS_ERR(skey_ref)) {
204 key_ref_put(skey_ref); 211 key_ref_put(skey_ref);
205 key_ref = make_key_ref(key, 1); 212 key_ref = make_key_ref(key, 1);
@@ -211,7 +218,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
211 * - the caller holds a spinlock, and thus the RCU read lock, making our 218 * - the caller holds a spinlock, and thus the RCU read lock, making our
212 * access to __current_cred() safe 219 * access to __current_cred() safe
213 */ 220 */
214 rc = key_task_permission(key_ref, cred, KEY_VIEW); 221 rc = key_task_permission(key_ref, ctx.cred, KEY_VIEW);
215 if (rc < 0) 222 if (rc < 0)
216 return 0; 223 return 0;
217 224
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a3410d605849..e68a3e0e7aa0 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -319,11 +319,7 @@ void key_fsgid_changed(struct task_struct *tsk)
319 * In the case of a successful return, the possession attribute is set on the 319 * In the case of a successful return, the possession attribute is set on the
320 * returned key reference. 320 * returned key reference.
321 */ 321 */
322key_ref_t search_my_process_keyrings(struct key_type *type, 322key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
323 const void *description,
324 key_match_func_t match,
325 bool no_state_check,
326 const struct cred *cred)
327{ 323{
328 key_ref_t key_ref, ret, err; 324 key_ref_t key_ref, ret, err;
329 325
@@ -339,10 +335,9 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
339 err = ERR_PTR(-EAGAIN); 335 err = ERR_PTR(-EAGAIN);
340 336
341 /* search the thread keyring first */ 337 /* search the thread keyring first */
342 if (cred->thread_keyring) { 338 if (ctx->cred->thread_keyring) {
343 key_ref = keyring_search_aux( 339 key_ref = keyring_search_aux(
344 make_key_ref(cred->thread_keyring, 1), 340 make_key_ref(ctx->cred->thread_keyring, 1), ctx);
345 cred, type, description, match, no_state_check);
346 if (!IS_ERR(key_ref)) 341 if (!IS_ERR(key_ref))
347 goto found; 342 goto found;
348 343
@@ -358,10 +353,9 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
358 } 353 }
359 354
360 /* search the process keyring second */ 355 /* search the process keyring second */
361 if (cred->process_keyring) { 356 if (ctx->cred->process_keyring) {
362 key_ref = keyring_search_aux( 357 key_ref = keyring_search_aux(
363 make_key_ref(cred->process_keyring, 1), 358 make_key_ref(ctx->cred->process_keyring, 1), ctx);
364 cred, type, description, match, no_state_check);
365 if (!IS_ERR(key_ref)) 359 if (!IS_ERR(key_ref))
366 goto found; 360 goto found;
367 361
@@ -379,11 +373,11 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
379 } 373 }
380 374
381 /* search the session keyring */ 375 /* search the session keyring */
382 if (cred->session_keyring) { 376 if (ctx->cred->session_keyring) {
383 rcu_read_lock(); 377 rcu_read_lock();
384 key_ref = keyring_search_aux( 378 key_ref = keyring_search_aux(
385 make_key_ref(rcu_dereference(cred->session_keyring), 1), 379 make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1),
386 cred, type, description, match, no_state_check); 380 ctx);
387 rcu_read_unlock(); 381 rcu_read_unlock();
388 382
389 if (!IS_ERR(key_ref)) 383 if (!IS_ERR(key_ref))
@@ -402,10 +396,10 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
402 } 396 }
403 } 397 }
404 /* or search the user-session keyring */ 398 /* or search the user-session keyring */
405 else if (cred->user->session_keyring) { 399 else if (ctx->cred->user->session_keyring) {
406 key_ref = keyring_search_aux( 400 key_ref = keyring_search_aux(
407 make_key_ref(cred->user->session_keyring, 1), 401 make_key_ref(ctx->cred->user->session_keyring, 1),
408 cred, type, description, match, no_state_check); 402 ctx);
409 if (!IS_ERR(key_ref)) 403 if (!IS_ERR(key_ref))
410 goto found; 404 goto found;
411 405
@@ -437,19 +431,14 @@ found:
437 * 431 *
438 * Return same as search_my_process_keyrings(). 432 * Return same as search_my_process_keyrings().
439 */ 433 */
440key_ref_t search_process_keyrings(struct key_type *type, 434key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
441 const void *description,
442 key_match_func_t match,
443 bool no_state_check,
444 const struct cred *cred)
445{ 435{
446 struct request_key_auth *rka; 436 struct request_key_auth *rka;
447 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; 437 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
448 438
449 might_sleep(); 439 might_sleep();
450 440
451 key_ref = search_my_process_keyrings(type, description, match, 441 key_ref = search_my_process_keyrings(ctx);
452 no_state_check, cred);
453 if (!IS_ERR(key_ref)) 442 if (!IS_ERR(key_ref))
454 goto found; 443 goto found;
455 err = key_ref; 444 err = key_ref;
@@ -458,19 +447,21 @@ key_ref_t search_process_keyrings(struct key_type *type,
458 * search the keyrings of the process mentioned there 447 * search the keyrings of the process mentioned there
459 * - we don't permit access to request_key auth keys via this method 448 * - we don't permit access to request_key auth keys via this method
460 */ 449 */
461 if (cred->request_key_auth && 450 if (ctx->cred->request_key_auth &&
462 cred == current_cred() && 451 ctx->cred == current_cred() &&
463 type != &key_type_request_key_auth 452 ctx->index_key.type != &key_type_request_key_auth
464 ) { 453 ) {
454 const struct cred *cred = ctx->cred;
455
465 /* defend against the auth key being revoked */ 456 /* defend against the auth key being revoked */
466 down_read(&cred->request_key_auth->sem); 457 down_read(&cred->request_key_auth->sem);
467 458
468 if (key_validate(cred->request_key_auth) == 0) { 459 if (key_validate(ctx->cred->request_key_auth) == 0) {
469 rka = cred->request_key_auth->payload.data; 460 rka = ctx->cred->request_key_auth->payload.data;
470 461
471 key_ref = search_process_keyrings(type, description, 462 ctx->cred = rka->cred;
472 match, no_state_check, 463 key_ref = search_process_keyrings(ctx);
473 rka->cred); 464 ctx->cred = cred;
474 465
475 up_read(&cred->request_key_auth->sem); 466 up_read(&cred->request_key_auth->sem);
476 467
@@ -524,19 +515,23 @@ int lookup_user_key_possessed(const struct key *key, const void *target)
524key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, 515key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
525 key_perm_t perm) 516 key_perm_t perm)
526{ 517{
518 struct keyring_search_context ctx = {
519 .match = lookup_user_key_possessed,
520 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
521 KEYRING_SEARCH_LOOKUP_DIRECT),
522 };
527 struct request_key_auth *rka; 523 struct request_key_auth *rka;
528 const struct cred *cred;
529 struct key *key; 524 struct key *key;
530 key_ref_t key_ref, skey_ref; 525 key_ref_t key_ref, skey_ref;
531 int ret; 526 int ret;
532 527
533try_again: 528try_again:
534 cred = get_current_cred(); 529 ctx.cred = get_current_cred();
535 key_ref = ERR_PTR(-ENOKEY); 530 key_ref = ERR_PTR(-ENOKEY);
536 531
537 switch (id) { 532 switch (id) {
538 case KEY_SPEC_THREAD_KEYRING: 533 case KEY_SPEC_THREAD_KEYRING:
539 if (!cred->thread_keyring) { 534 if (!ctx.cred->thread_keyring) {
540 if (!(lflags & KEY_LOOKUP_CREATE)) 535 if (!(lflags & KEY_LOOKUP_CREATE))
541 goto error; 536 goto error;
542 537
@@ -548,13 +543,13 @@ try_again:
548 goto reget_creds; 543 goto reget_creds;
549 } 544 }
550 545
551 key = cred->thread_keyring; 546 key = ctx.cred->thread_keyring;
552 atomic_inc(&key->usage); 547 atomic_inc(&key->usage);
553 key_ref = make_key_ref(key, 1); 548 key_ref = make_key_ref(key, 1);
554 break; 549 break;
555 550
556 case KEY_SPEC_PROCESS_KEYRING: 551 case KEY_SPEC_PROCESS_KEYRING:
557 if (!cred->process_keyring) { 552 if (!ctx.cred->process_keyring) {
558 if (!(lflags & KEY_LOOKUP_CREATE)) 553 if (!(lflags & KEY_LOOKUP_CREATE))
559 goto error; 554 goto error;
560 555
@@ -566,13 +561,13 @@ try_again:
566 goto reget_creds; 561 goto reget_creds;
567 } 562 }
568 563
569 key = cred->process_keyring; 564 key = ctx.cred->process_keyring;
570 atomic_inc(&key->usage); 565 atomic_inc(&key->usage);
571 key_ref = make_key_ref(key, 1); 566 key_ref = make_key_ref(key, 1);
572 break; 567 break;
573 568
574 case KEY_SPEC_SESSION_KEYRING: 569 case KEY_SPEC_SESSION_KEYRING:
575 if (!cred->session_keyring) { 570 if (!ctx.cred->session_keyring) {
576 /* always install a session keyring upon access if one 571 /* always install a session keyring upon access if one
577 * doesn't exist yet */ 572 * doesn't exist yet */
578 ret = install_user_keyrings(); 573 ret = install_user_keyrings();
@@ -582,13 +577,13 @@ try_again:
582 ret = join_session_keyring(NULL); 577 ret = join_session_keyring(NULL);
583 else 578 else
584 ret = install_session_keyring( 579 ret = install_session_keyring(
585 cred->user->session_keyring); 580 ctx.cred->user->session_keyring);
586 581
587 if (ret < 0) 582 if (ret < 0)
588 goto error; 583 goto error;
589 goto reget_creds; 584 goto reget_creds;
590 } else if (cred->session_keyring == 585 } else if (ctx.cred->session_keyring ==
591 cred->user->session_keyring && 586 ctx.cred->user->session_keyring &&
592 lflags & KEY_LOOKUP_CREATE) { 587 lflags & KEY_LOOKUP_CREATE) {
593 ret = join_session_keyring(NULL); 588 ret = join_session_keyring(NULL);
594 if (ret < 0) 589 if (ret < 0)
@@ -597,32 +592,32 @@ try_again:
597 } 592 }
598 593
599 rcu_read_lock(); 594 rcu_read_lock();
600 key = rcu_dereference(cred->session_keyring); 595 key = rcu_dereference(ctx.cred->session_keyring);
601 atomic_inc(&key->usage); 596 atomic_inc(&key->usage);
602 rcu_read_unlock(); 597 rcu_read_unlock();
603 key_ref = make_key_ref(key, 1); 598 key_ref = make_key_ref(key, 1);
604 break; 599 break;
605 600
606 case KEY_SPEC_USER_KEYRING: 601 case KEY_SPEC_USER_KEYRING:
607 if (!cred->user->uid_keyring) { 602 if (!ctx.cred->user->uid_keyring) {
608 ret = install_user_keyrings(); 603 ret = install_user_keyrings();
609 if (ret < 0) 604 if (ret < 0)
610 goto error; 605 goto error;
611 } 606 }
612 607
613 key = cred->user->uid_keyring; 608 key = ctx.cred->user->uid_keyring;
614 atomic_inc(&key->usage); 609 atomic_inc(&key->usage);
615 key_ref = make_key_ref(key, 1); 610 key_ref = make_key_ref(key, 1);
616 break; 611 break;
617 612
618 case KEY_SPEC_USER_SESSION_KEYRING: 613 case KEY_SPEC_USER_SESSION_KEYRING:
619 if (!cred->user->session_keyring) { 614 if (!ctx.cred->user->session_keyring) {
620 ret = install_user_keyrings(); 615 ret = install_user_keyrings();
621 if (ret < 0) 616 if (ret < 0)
622 goto error; 617 goto error;
623 } 618 }
624 619
625 key = cred->user->session_keyring; 620 key = ctx.cred->user->session_keyring;
626 atomic_inc(&key->usage); 621 atomic_inc(&key->usage);
627 key_ref = make_key_ref(key, 1); 622 key_ref = make_key_ref(key, 1);
628 break; 623 break;
@@ -633,7 +628,7 @@ try_again:
633 goto error; 628 goto error;
634 629
635 case KEY_SPEC_REQKEY_AUTH_KEY: 630 case KEY_SPEC_REQKEY_AUTH_KEY:
636 key = cred->request_key_auth; 631 key = ctx.cred->request_key_auth;
637 if (!key) 632 if (!key)
638 goto error; 633 goto error;
639 634
@@ -642,20 +637,20 @@ try_again:
642 break; 637 break;
643 638
644 case KEY_SPEC_REQUESTOR_KEYRING: 639 case KEY_SPEC_REQUESTOR_KEYRING:
645 if (!cred->request_key_auth) 640 if (!ctx.cred->request_key_auth)
646 goto error; 641 goto error;
647 642
648 down_read(&cred->request_key_auth->sem); 643 down_read(&ctx.cred->request_key_auth->sem);
649 if (test_bit(KEY_FLAG_REVOKED, 644 if (test_bit(KEY_FLAG_REVOKED,
650 &cred->request_key_auth->flags)) { 645 &ctx.cred->request_key_auth->flags)) {
651 key_ref = ERR_PTR(-EKEYREVOKED); 646 key_ref = ERR_PTR(-EKEYREVOKED);
652 key = NULL; 647 key = NULL;
653 } else { 648 } else {
654 rka = cred->request_key_auth->payload.data; 649 rka = ctx.cred->request_key_auth->payload.data;
655 key = rka->dest_keyring; 650 key = rka->dest_keyring;
656 atomic_inc(&key->usage); 651 atomic_inc(&key->usage);
657 } 652 }
658 up_read(&cred->request_key_auth->sem); 653 up_read(&ctx.cred->request_key_auth->sem);
659 if (!key) 654 if (!key)
660 goto error; 655 goto error;
661 key_ref = make_key_ref(key, 1); 656 key_ref = make_key_ref(key, 1);
@@ -675,9 +670,13 @@ try_again:
675 key_ref = make_key_ref(key, 0); 670 key_ref = make_key_ref(key, 0);
676 671
677 /* check to see if we possess the key */ 672 /* check to see if we possess the key */
678 skey_ref = search_process_keyrings(key->type, key, 673 ctx.index_key.type = key->type;
679 lookup_user_key_possessed, 674 ctx.index_key.description = key->description;
680 true, cred); 675 ctx.index_key.desc_len = strlen(key->description);
676 ctx.match_data = key;
677 kdebug("check possessed");
678 skey_ref = search_process_keyrings(&ctx);
679 kdebug("possessed=%p", skey_ref);
681 680
682 if (!IS_ERR(skey_ref)) { 681 if (!IS_ERR(skey_ref)) {
683 key_put(key); 682 key_put(key);
@@ -717,14 +716,14 @@ try_again:
717 goto invalid_key; 716 goto invalid_key;
718 717
719 /* check the permissions */ 718 /* check the permissions */
720 ret = key_task_permission(key_ref, cred, perm); 719 ret = key_task_permission(key_ref, ctx.cred, perm);
721 if (ret < 0) 720 if (ret < 0)
722 goto invalid_key; 721 goto invalid_key;
723 722
724 key->last_used_at = current_kernel_time().tv_sec; 723 key->last_used_at = current_kernel_time().tv_sec;
725 724
726error: 725error:
727 put_cred(cred); 726 put_cred(ctx.cred);
728 return key_ref; 727 return key_ref;
729 728
730invalid_key: 729invalid_key:
@@ -735,7 +734,7 @@ invalid_key:
735 /* if we attempted to install a keyring, then it may have caused new 734 /* if we attempted to install a keyring, then it may have caused new
736 * creds to be installed */ 735 * creds to be installed */
737reget_creds: 736reget_creds:
738 put_cred(cred); 737 put_cred(ctx.cred);
739 goto try_again; 738 goto try_again;
740} 739}
741 740
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 586cb79ee82d..ab75df4745af 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -345,38 +345,34 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
345 * May return a key that's already under construction instead if there was a 345 * May return a key that's already under construction instead if there was a
346 * race between two thread calling request_key(). 346 * race between two thread calling request_key().
347 */ 347 */
348static int construct_alloc_key(struct key_type *type, 348static int construct_alloc_key(struct keyring_search_context *ctx,
349 const char *description,
350 struct key *dest_keyring, 349 struct key *dest_keyring,
351 unsigned long flags, 350 unsigned long flags,
352 struct key_user *user, 351 struct key_user *user,
353 struct key **_key) 352 struct key **_key)
354{ 353{
355 const struct keyring_index_key index_key = {
356 .type = type,
357 .description = description,
358 .desc_len = strlen(description),
359 };
360 const struct cred *cred = current_cred();
361 unsigned long prealloc; 354 unsigned long prealloc;
362 struct key *key; 355 struct key *key;
363 key_perm_t perm; 356 key_perm_t perm;
364 key_ref_t key_ref; 357 key_ref_t key_ref;
365 int ret; 358 int ret;
366 359
367 kenter("%s,%s,,,", type->name, description); 360 kenter("%s,%s,,,",
361 ctx->index_key.type->name, ctx->index_key.description);
368 362
369 *_key = NULL; 363 *_key = NULL;
370 mutex_lock(&user->cons_lock); 364 mutex_lock(&user->cons_lock);
371 365
372 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 366 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
373 perm |= KEY_USR_VIEW; 367 perm |= KEY_USR_VIEW;
374 if (type->read) 368 if (ctx->index_key.type->read)
375 perm |= KEY_POS_READ; 369 perm |= KEY_POS_READ;
376 if (type == &key_type_keyring || type->update) 370 if (ctx->index_key.type == &key_type_keyring ||
371 ctx->index_key.type->update)
377 perm |= KEY_POS_WRITE; 372 perm |= KEY_POS_WRITE;
378 373
379 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, 374 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
375 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
380 perm, flags); 376 perm, flags);
381 if (IS_ERR(key)) 377 if (IS_ERR(key))
382 goto alloc_failed; 378 goto alloc_failed;
@@ -384,7 +380,7 @@ static int construct_alloc_key(struct key_type *type,
384 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 380 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
385 381
386 if (dest_keyring) { 382 if (dest_keyring) {
387 ret = __key_link_begin(dest_keyring, &index_key, &prealloc); 383 ret = __key_link_begin(dest_keyring, &ctx->index_key, &prealloc);
388 if (ret < 0) 384 if (ret < 0)
389 goto link_prealloc_failed; 385 goto link_prealloc_failed;
390 } 386 }
@@ -394,8 +390,7 @@ static int construct_alloc_key(struct key_type *type,
394 * waited for locks */ 390 * waited for locks */
395 mutex_lock(&key_construction_mutex); 391 mutex_lock(&key_construction_mutex);
396 392
397 key_ref = search_process_keyrings(type, description, type->match, 393 key_ref = search_process_keyrings(ctx);
398 false, cred);
399 if (!IS_ERR(key_ref)) 394 if (!IS_ERR(key_ref))
400 goto key_already_present; 395 goto key_already_present;
401 396
@@ -404,7 +399,7 @@ static int construct_alloc_key(struct key_type *type,
404 399
405 mutex_unlock(&key_construction_mutex); 400 mutex_unlock(&key_construction_mutex);
406 if (dest_keyring) 401 if (dest_keyring)
407 __key_link_end(dest_keyring, &index_key, prealloc); 402 __key_link_end(dest_keyring, &ctx->index_key, prealloc);
408 mutex_unlock(&user->cons_lock); 403 mutex_unlock(&user->cons_lock);
409 *_key = key; 404 *_key = key;
410 kleave(" = 0 [%d]", key_serial(key)); 405 kleave(" = 0 [%d]", key_serial(key));
@@ -420,7 +415,7 @@ key_already_present:
420 ret = __key_link_check_live_key(dest_keyring, key); 415 ret = __key_link_check_live_key(dest_keyring, key);
421 if (ret == 0) 416 if (ret == 0)
422 __key_link(dest_keyring, key, &prealloc); 417 __key_link(dest_keyring, key, &prealloc);
423 __key_link_end(dest_keyring, &index_key, prealloc); 418 __key_link_end(dest_keyring, &ctx->index_key, prealloc);
424 if (ret < 0) 419 if (ret < 0)
425 goto link_check_failed; 420 goto link_check_failed;
426 } 421 }
@@ -449,8 +444,7 @@ alloc_failed:
449/* 444/*
450 * Commence key construction. 445 * Commence key construction.
451 */ 446 */
452static struct key *construct_key_and_link(struct key_type *type, 447static struct key *construct_key_and_link(struct keyring_search_context *ctx,
453 const char *description,
454 const char *callout_info, 448 const char *callout_info,
455 size_t callout_len, 449 size_t callout_len,
456 void *aux, 450 void *aux,
@@ -469,8 +463,7 @@ static struct key *construct_key_and_link(struct key_type *type,
469 463
470 construct_get_dest_keyring(&dest_keyring); 464 construct_get_dest_keyring(&dest_keyring);
471 465
472 ret = construct_alloc_key(type, description, dest_keyring, flags, user, 466 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
473 &key);
474 key_user_put(user); 467 key_user_put(user);
475 468
476 if (ret == 0) { 469 if (ret == 0) {
@@ -534,18 +527,24 @@ struct key *request_key_and_link(struct key_type *type,
534 struct key *dest_keyring, 527 struct key *dest_keyring,
535 unsigned long flags) 528 unsigned long flags)
536{ 529{
537 const struct cred *cred = current_cred(); 530 struct keyring_search_context ctx = {
531 .index_key.type = type,
532 .index_key.description = description,
533 .cred = current_cred(),
534 .match = type->match,
535 .match_data = description,
536 .flags = KEYRING_SEARCH_LOOKUP_DIRECT,
537 };
538 struct key *key; 538 struct key *key;
539 key_ref_t key_ref; 539 key_ref_t key_ref;
540 int ret; 540 int ret;
541 541
542 kenter("%s,%s,%p,%zu,%p,%p,%lx", 542 kenter("%s,%s,%p,%zu,%p,%p,%lx",
543 type->name, description, callout_info, callout_len, aux, 543 ctx.index_key.type->name, ctx.index_key.description,
544 dest_keyring, flags); 544 callout_info, callout_len, aux, dest_keyring, flags);
545 545
546 /* search all the process keyrings for a key */ 546 /* search all the process keyrings for a key */
547 key_ref = search_process_keyrings(type, description, type->match, 547 key_ref = search_process_keyrings(&ctx);
548 false, cred);
549 548
550 if (!IS_ERR(key_ref)) { 549 if (!IS_ERR(key_ref)) {
551 key = key_ref_to_ptr(key_ref); 550 key = key_ref_to_ptr(key_ref);
@@ -568,9 +567,8 @@ struct key *request_key_and_link(struct key_type *type,
568 if (!callout_info) 567 if (!callout_info)
569 goto error; 568 goto error;
570 569
571 key = construct_key_and_link(type, description, callout_info, 570 key = construct_key_and_link(&ctx, callout_info, callout_len,
572 callout_len, aux, dest_keyring, 571 aux, dest_keyring, flags);
573 flags);
574 } 572 }
575 573
576error: 574error:
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 92077de555df..8d09852854ca 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -239,15 +239,17 @@ static int key_get_instantiation_authkey_match(const struct key *key,
239 */ 239 */
240struct key *key_get_instantiation_authkey(key_serial_t target_id) 240struct key *key_get_instantiation_authkey(key_serial_t target_id)
241{ 241{
242 const struct cred *cred = current_cred(); 242 struct keyring_search_context ctx = {
243 .index_key.type = &key_type_request_key_auth,
244 .cred = current_cred(),
245 .match = key_get_instantiation_authkey_match,
246 .match_data = (void *)(unsigned long)target_id,
247 .flags = KEYRING_SEARCH_LOOKUP_DIRECT,
248 };
243 struct key *authkey; 249 struct key *authkey;
244 key_ref_t authkey_ref; 250 key_ref_t authkey_ref;
245 251
246 authkey_ref = search_process_keyrings( 252 authkey_ref = search_process_keyrings(&ctx);
247 &key_type_request_key_auth,
248 (void *) (unsigned long) target_id,
249 key_get_instantiation_authkey_match,
250 false, cred);
251 253
252 if (IS_ERR(authkey_ref)) { 254 if (IS_ERR(authkey_ref)) {
253 authkey = ERR_CAST(authkey_ref); 255 authkey = ERR_CAST(authkey_ref);
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 55dc88939185..faa2caeb593f 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -25,14 +25,15 @@ static int logon_vet_description(const char *desc);
25 * arbitrary blob of data as the payload 25 * arbitrary blob of data as the payload
26 */ 26 */
27struct key_type key_type_user = { 27struct key_type key_type_user = {
28 .name = "user", 28 .name = "user",
29 .instantiate = user_instantiate, 29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
30 .update = user_update, 30 .instantiate = user_instantiate,
31 .match = user_match, 31 .update = user_update,
32 .revoke = user_revoke, 32 .match = user_match,
33 .destroy = user_destroy, 33 .revoke = user_revoke,
34 .describe = user_describe, 34 .destroy = user_destroy,
35 .read = user_read, 35 .describe = user_describe,
36 .read = user_read,
36}; 37};
37 38
38EXPORT_SYMBOL_GPL(key_type_user); 39EXPORT_SYMBOL_GPL(key_type_user);
@@ -45,6 +46,7 @@ EXPORT_SYMBOL_GPL(key_type_user);
45 */ 46 */
46struct key_type key_type_logon = { 47struct key_type key_type_logon = {
47 .name = "logon", 48 .name = "logon",
49 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
48 .instantiate = user_instantiate, 50 .instantiate = user_instantiate,
49 .update = user_update, 51 .update = user_update,
50 .match = user_match, 52 .match = user_match,