diff options
author | David Howells <dhowells@redhat.com> | 2013-09-24 05:35:15 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2013-09-24 05:35:15 -0400 |
commit | 4bdf0bc300314141e5475e145acb8b5ad846f00d (patch) | |
tree | ecf5a1d74d507410a9defa32edb4ea73edb9d205 /security/keys/request_key.c | |
parent | 16feef4340172b7dbb9cba60850e78fa6388adf1 (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>
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: |