diff options
Diffstat (limited to 'security/keys/process_keys.c')
| -rw-r--r-- | security/keys/process_keys.c | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 6b8e4ff4cc6..f8e7251ae2c 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
| @@ -309,22 +309,19 @@ void key_fsgid_changed(struct task_struct *tsk) | |||
| 309 | 309 | ||
| 310 | /*****************************************************************************/ | 310 | /*****************************************************************************/ |
| 311 | /* | 311 | /* |
| 312 | * search the process keyrings for the first matching key | 312 | * search only my process keyrings for the first matching key |
| 313 | * - we use the supplied match function to see if the description (or other | 313 | * - we use the supplied match function to see if the description (or other |
| 314 | * feature of interest) matches | 314 | * feature of interest) matches |
| 315 | * - we return -EAGAIN if we didn't find any matching key | 315 | * - we return -EAGAIN if we didn't find any matching key |
| 316 | * - we return -ENOKEY if we found only negative matching keys | 316 | * - we return -ENOKEY if we found only negative matching keys |
| 317 | */ | 317 | */ |
| 318 | key_ref_t search_process_keyrings(struct key_type *type, | 318 | key_ref_t search_my_process_keyrings(struct key_type *type, |
| 319 | const void *description, | 319 | const void *description, |
| 320 | key_match_func_t match, | 320 | key_match_func_t match, |
| 321 | const struct cred *cred) | 321 | const struct cred *cred) |
| 322 | { | 322 | { |
| 323 | struct request_key_auth *rka; | ||
| 324 | key_ref_t key_ref, ret, err; | 323 | key_ref_t key_ref, ret, err; |
| 325 | 324 | ||
| 326 | might_sleep(); | ||
| 327 | |||
| 328 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were | 325 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
| 329 | * searchable, but we failed to find a key or we found a negative key; | 326 | * searchable, but we failed to find a key or we found a negative key; |
| 330 | * otherwise we want to return a sample error (probably -EACCES) if | 327 | * otherwise we want to return a sample error (probably -EACCES) if |
| @@ -424,6 +421,36 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
| 424 | } | 421 | } |
| 425 | } | 422 | } |
| 426 | 423 | ||
| 424 | /* no key - decide on the error we're going to go for */ | ||
| 425 | key_ref = ret ? ret : err; | ||
| 426 | |||
| 427 | found: | ||
| 428 | return key_ref; | ||
| 429 | } | ||
| 430 | |||
| 431 | /*****************************************************************************/ | ||
| 432 | /* | ||
| 433 | * search the process keyrings for the first matching key | ||
| 434 | * - we use the supplied match function to see if the description (or other | ||
| 435 | * feature of interest) matches | ||
| 436 | * - we return -EAGAIN if we didn't find any matching key | ||
| 437 | * - we return -ENOKEY if we found only negative matching keys | ||
| 438 | */ | ||
| 439 | key_ref_t search_process_keyrings(struct key_type *type, | ||
| 440 | const void *description, | ||
| 441 | key_match_func_t match, | ||
| 442 | const struct cred *cred) | ||
| 443 | { | ||
| 444 | struct request_key_auth *rka; | ||
| 445 | key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; | ||
| 446 | |||
| 447 | might_sleep(); | ||
| 448 | |||
| 449 | key_ref = search_my_process_keyrings(type, description, match, cred); | ||
| 450 | if (!IS_ERR(key_ref)) | ||
| 451 | goto found; | ||
| 452 | err = key_ref; | ||
| 453 | |||
| 427 | /* if this process has an instantiation authorisation key, then we also | 454 | /* if this process has an instantiation authorisation key, then we also |
| 428 | * search the keyrings of the process mentioned there | 455 | * search the keyrings of the process mentioned there |
| 429 | * - we don't permit access to request_key auth keys via this method | 456 | * - we don't permit access to request_key auth keys via this method |
| @@ -446,24 +473,19 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
| 446 | if (!IS_ERR(key_ref)) | 473 | if (!IS_ERR(key_ref)) |
| 447 | goto found; | 474 | goto found; |
| 448 | 475 | ||
| 449 | switch (PTR_ERR(key_ref)) { | 476 | ret = key_ref; |
| 450 | case -EAGAIN: /* no key */ | ||
| 451 | if (ret) | ||
| 452 | break; | ||
| 453 | case -ENOKEY: /* negative key */ | ||
| 454 | ret = key_ref; | ||
| 455 | break; | ||
| 456 | default: | ||
| 457 | err = key_ref; | ||
| 458 | break; | ||
| 459 | } | ||
| 460 | } else { | 477 | } else { |
| 461 | up_read(&cred->request_key_auth->sem); | 478 | up_read(&cred->request_key_auth->sem); |
| 462 | } | 479 | } |
| 463 | } | 480 | } |
| 464 | 481 | ||
| 465 | /* no key - decide on the error we're going to go for */ | 482 | /* no key - decide on the error we're going to go for */ |
| 466 | key_ref = ret ? ret : err; | 483 | if (err == ERR_PTR(-ENOKEY) || ret == ERR_PTR(-ENOKEY)) |
| 484 | key_ref = ERR_PTR(-ENOKEY); | ||
| 485 | else if (err == ERR_PTR(-EACCES)) | ||
| 486 | key_ref = ret; | ||
| 487 | else | ||
| 488 | key_ref = err; | ||
| 467 | 489 | ||
| 468 | found: | 490 | found: |
| 469 | return key_ref; | 491 | return key_ref; |
| @@ -474,7 +496,7 @@ found: | |||
| 474 | /* | 496 | /* |
| 475 | * see if the key we're looking at is the target key | 497 | * see if the key we're looking at is the target key |
| 476 | */ | 498 | */ |
| 477 | static int lookup_user_key_possessed(const struct key *key, const void *target) | 499 | int lookup_user_key_possessed(const struct key *key, const void *target) |
| 478 | { | 500 | { |
| 479 | return key == target; | 501 | return key == target; |
| 480 | 502 | ||
