diff options
author | David Howells <dhowells@redhat.com> | 2010-06-11 12:31:10 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:27 -0400 |
commit | 927942aabbbe506bf9bc70a16dc5460ecc64c148 (patch) | |
tree | 2c53ccb405bd4afb03ff9f7acab892fafc7e9b0f /security/keys/process_keys.c | |
parent | 9156235b3427d6f01c5c95022f72f381f07583f5 (diff) |
KEYS: Make /proc/keys check to see if a key is possessed before security check
Make /proc/keys check to see if the calling process possesses each key before
performing the security check. The possession check can be skipped if the key
doesn't have the possessor-view permission bit set.
This causes the keys a process possesses to show up in /proc/keys, even if they
don't have matching user/group/other view permissions.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
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 6b8e4ff4cc68..f8e7251ae2c8 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 | ||