aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index c411f9bb156b..381411941cc1 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -345,33 +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 cred *cred = current_cred(); 354 struct assoc_array_edit *edit;
356 unsigned long prealloc;
357 struct key *key; 355 struct key *key;
358 key_perm_t perm; 356 key_perm_t perm;
359 key_ref_t key_ref; 357 key_ref_t key_ref;
360 int ret; 358 int ret;
361 359
362 kenter("%s,%s,,,", type->name, description); 360 kenter("%s,%s,,,",
361 ctx->index_key.type->name, ctx->index_key.description);
363 362
364 *_key = NULL; 363 *_key = NULL;
365 mutex_lock(&user->cons_lock); 364 mutex_lock(&user->cons_lock);
366 365
367 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;
368 perm |= KEY_USR_VIEW; 367 perm |= KEY_USR_VIEW;
369 if (type->read) 368 if (ctx->index_key.type->read)
370 perm |= KEY_POS_READ; 369 perm |= KEY_POS_READ;
371 if (type == &key_type_keyring || type->update) 370 if (ctx->index_key.type == &key_type_keyring ||
371 ctx->index_key.type->update)
372 perm |= KEY_POS_WRITE; 372 perm |= KEY_POS_WRITE;
373 373
374 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,
375 perm, flags); 376 perm, flags);
376 if (IS_ERR(key)) 377 if (IS_ERR(key))
377 goto alloc_failed; 378 goto alloc_failed;
@@ -379,8 +380,7 @@ static int construct_alloc_key(struct key_type *type,
379 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 380 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
380 381
381 if (dest_keyring) { 382 if (dest_keyring) {
382 ret = __key_link_begin(dest_keyring, type, description, 383 ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit);
383 &prealloc);
384 if (ret < 0) 384 if (ret < 0)
385 goto link_prealloc_failed; 385 goto link_prealloc_failed;
386 } 386 }
@@ -390,16 +390,16 @@ static int construct_alloc_key(struct key_type *type,
390 * waited for locks */ 390 * waited for locks */
391 mutex_lock(&key_construction_mutex); 391 mutex_lock(&key_construction_mutex);
392 392
393 key_ref = search_process_keyrings(type, description, type->match, cred); 393 key_ref = search_process_keyrings(ctx);
394 if (!IS_ERR(key_ref)) 394 if (!IS_ERR(key_ref))
395 goto key_already_present; 395 goto key_already_present;
396 396
397 if (dest_keyring) 397 if (dest_keyring)
398 __key_link(dest_keyring, key, &prealloc); 398 __key_link(key, &edit);
399 399
400 mutex_unlock(&key_construction_mutex); 400 mutex_unlock(&key_construction_mutex);
401 if (dest_keyring) 401 if (dest_keyring)
402 __key_link_end(dest_keyring, type, prealloc); 402 __key_link_end(dest_keyring, &ctx->index_key, edit);
403 mutex_unlock(&user->cons_lock); 403 mutex_unlock(&user->cons_lock);
404 *_key = key; 404 *_key = key;
405 kleave(" = 0 [%d]", key_serial(key)); 405 kleave(" = 0 [%d]", key_serial(key));
@@ -414,8 +414,8 @@ key_already_present:
414 if (dest_keyring) { 414 if (dest_keyring) {
415 ret = __key_link_check_live_key(dest_keyring, key); 415 ret = __key_link_check_live_key(dest_keyring, key);
416 if (ret == 0) 416 if (ret == 0)
417 __key_link(dest_keyring, key, &prealloc); 417 __key_link(key, &edit);
418 __key_link_end(dest_keyring, type, prealloc); 418 __key_link_end(dest_keyring, &ctx->index_key, edit);
419 if (ret < 0) 419 if (ret < 0)
420 goto link_check_failed; 420 goto link_check_failed;
421 } 421 }
@@ -444,8 +444,7 @@ alloc_failed:
444/* 444/*
445 * Commence key construction. 445 * Commence key construction.
446 */ 446 */
447static struct key *construct_key_and_link(struct key_type *type, 447static struct key *construct_key_and_link(struct keyring_search_context *ctx,
448 const char *description,
449 const char *callout_info, 448 const char *callout_info,
450 size_t callout_len, 449 size_t callout_len,
451 void *aux, 450 void *aux,
@@ -464,8 +463,7 @@ static struct key *construct_key_and_link(struct key_type *type,
464 463
465 construct_get_dest_keyring(&dest_keyring); 464 construct_get_dest_keyring(&dest_keyring);
466 465
467 ret = construct_alloc_key(type, description, dest_keyring, flags, user, 466 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
468 &key);
469 key_user_put(user); 467 key_user_put(user);
470 468
471 if (ret == 0) { 469 if (ret == 0) {
@@ -529,17 +527,24 @@ struct key *request_key_and_link(struct key_type *type,
529 struct key *dest_keyring, 527 struct key *dest_keyring,
530 unsigned long flags) 528 unsigned long flags)
531{ 529{
532 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 };
533 struct key *key; 538 struct key *key;
534 key_ref_t key_ref; 539 key_ref_t key_ref;
535 int ret; 540 int ret;
536 541
537 kenter("%s,%s,%p,%zu,%p,%p,%lx", 542 kenter("%s,%s,%p,%zu,%p,%p,%lx",
538 type->name, description, callout_info, callout_len, aux, 543 ctx.index_key.type->name, ctx.index_key.description,
539 dest_keyring, flags); 544 callout_info, callout_len, aux, dest_keyring, flags);
540 545
541 /* search all the process keyrings for a key */ 546 /* search all the process keyrings for a key */
542 key_ref = search_process_keyrings(type, description, type->match, cred); 547 key_ref = search_process_keyrings(&ctx);
543 548
544 if (!IS_ERR(key_ref)) { 549 if (!IS_ERR(key_ref)) {
545 key = key_ref_to_ptr(key_ref); 550 key = key_ref_to_ptr(key_ref);
@@ -562,9 +567,8 @@ struct key *request_key_and_link(struct key_type *type,
562 if (!callout_info) 567 if (!callout_info)
563 goto error; 568 goto error;
564 569
565 key = construct_key_and_link(type, description, callout_info, 570 key = construct_key_and_link(&ctx, callout_info, callout_len,
566 callout_len, aux, dest_keyring, 571 aux, dest_keyring, flags);
567 flags);
568 } 572 }
569 573
570error: 574error:
@@ -592,8 +596,10 @@ int wait_for_key_construction(struct key *key, bool intr)
592 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 596 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
593 if (ret < 0) 597 if (ret < 0)
594 return ret; 598 return ret;
595 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 599 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
600 smp_rmb();
596 return key->type_data.reject_error; 601 return key->type_data.reject_error;
602 }
597 return key_validate(key); 603 return key_validate(key);
598} 604}
599EXPORT_SYMBOL(wait_for_key_construction); 605EXPORT_SYMBOL(wait_for_key_construction);