diff options
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r-- | security/keys/request_key.c | 56 |
1 files changed, 27 insertions, 29 deletions
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 | */ |
348 | static int construct_alloc_key(struct key_type *type, | 348 | static 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 | */ |
452 | static struct key *construct_key_and_link(struct key_type *type, | 447 | static 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 | ||
576 | error: | 574 | error: |