diff options
Diffstat (limited to 'security/keys/request_key.c')
| -rw-r--r-- | security/keys/request_key.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 90c1506d007c..5cc4bba70db6 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
| 9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | * | ||
| 11 | * See Documentation/keys-request-key.txt | ||
| 10 | */ | 12 | */ |
| 11 | 13 | ||
| 12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| @@ -129,7 +131,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
| 129 | 131 | ||
| 130 | /* create a key and add it to the queue */ | 132 | /* create a key and add it to the queue */ |
| 131 | key = key_alloc(type, description, | 133 | key = key_alloc(type, description, |
| 132 | current->fsuid, current->fsgid, KEY_USR_ALL, 0); | 134 | current->fsuid, current->fsgid, KEY_POS_ALL, 0); |
| 133 | if (IS_ERR(key)) | 135 | if (IS_ERR(key)) |
| 134 | goto alloc_failed; | 136 | goto alloc_failed; |
| 135 | 137 | ||
| @@ -365,14 +367,24 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 365 | { | 367 | { |
| 366 | struct key_user *user; | 368 | struct key_user *user; |
| 367 | struct key *key; | 369 | struct key *key; |
| 370 | key_ref_t key_ref; | ||
| 368 | 371 | ||
| 369 | kenter("%s,%s,%s,%p", | 372 | kenter("%s,%s,%s,%p", |
| 370 | type->name, description, callout_info, dest_keyring); | 373 | type->name, description, callout_info, dest_keyring); |
| 371 | 374 | ||
| 372 | /* search all the process keyrings for a key */ | 375 | /* search all the process keyrings for a key */ |
| 373 | key = search_process_keyrings(type, description, type->match, current); | 376 | key_ref = search_process_keyrings(type, description, type->match, |
| 377 | current); | ||
| 378 | |||
| 379 | kdebug("search 1: %p", key_ref); | ||
| 374 | 380 | ||
| 375 | if (PTR_ERR(key) == -EAGAIN) { | 381 | if (!IS_ERR(key_ref)) { |
| 382 | key = key_ref_to_ptr(key_ref); | ||
| 383 | } | ||
| 384 | else if (PTR_ERR(key_ref) != -EAGAIN) { | ||
| 385 | key = ERR_PTR(PTR_ERR(key_ref)); | ||
| 386 | } | ||
| 387 | else { | ||
| 376 | /* the search failed, but the keyrings were searchable, so we | 388 | /* the search failed, but the keyrings were searchable, so we |
| 377 | * should consult userspace if we can */ | 389 | * should consult userspace if we can */ |
| 378 | key = ERR_PTR(-ENOKEY); | 390 | key = ERR_PTR(-ENOKEY); |
| @@ -384,7 +396,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 384 | if (!user) | 396 | if (!user) |
| 385 | goto nomem; | 397 | goto nomem; |
| 386 | 398 | ||
| 387 | do { | 399 | for (;;) { |
| 388 | if (signal_pending(current)) | 400 | if (signal_pending(current)) |
| 389 | goto interrupted; | 401 | goto interrupted; |
| 390 | 402 | ||
| @@ -397,10 +409,22 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 397 | 409 | ||
| 398 | /* someone else made the key we want, so we need to | 410 | /* someone else made the key we want, so we need to |
| 399 | * search again as it might now be available to us */ | 411 | * search again as it might now be available to us */ |
| 400 | key = search_process_keyrings(type, description, | 412 | key_ref = search_process_keyrings(type, description, |
| 401 | type->match, current); | 413 | type->match, |
| 414 | current); | ||
| 415 | |||
| 416 | kdebug("search 2: %p", key_ref); | ||
| 402 | 417 | ||
| 403 | } while (PTR_ERR(key) == -EAGAIN); | 418 | if (!IS_ERR(key_ref)) { |
| 419 | key = key_ref_to_ptr(key_ref); | ||
| 420 | break; | ||
| 421 | } | ||
| 422 | |||
| 423 | if (PTR_ERR(key_ref) != -EAGAIN) { | ||
| 424 | key = ERR_PTR(PTR_ERR(key_ref)); | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | } | ||
| 404 | 428 | ||
| 405 | key_user_put(user); | 429 | key_user_put(user); |
| 406 | 430 | ||
