diff options
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r-- | security/keys/process_keys.c | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 566b1cc0118a..74cb79eb917e 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -270,9 +270,14 @@ int copy_thread_group_keys(struct task_struct *tsk) | |||
270 | int copy_keys(unsigned long clone_flags, struct task_struct *tsk) | 270 | int copy_keys(unsigned long clone_flags, struct task_struct *tsk) |
271 | { | 271 | { |
272 | key_check(tsk->thread_keyring); | 272 | key_check(tsk->thread_keyring); |
273 | key_check(tsk->request_key_auth); | ||
273 | 274 | ||
274 | /* no thread keyring yet */ | 275 | /* no thread keyring yet */ |
275 | tsk->thread_keyring = NULL; | 276 | tsk->thread_keyring = NULL; |
277 | |||
278 | /* copy the request_key() authorisation for this thread */ | ||
279 | key_get(tsk->request_key_auth); | ||
280 | |||
276 | return 0; | 281 | return 0; |
277 | 282 | ||
278 | } /* end copy_keys() */ | 283 | } /* end copy_keys() */ |
@@ -290,11 +295,12 @@ void exit_thread_group_keys(struct signal_struct *tg) | |||
290 | 295 | ||
291 | /*****************************************************************************/ | 296 | /*****************************************************************************/ |
292 | /* | 297 | /* |
293 | * dispose of keys upon thread exit | 298 | * dispose of per-thread keys upon thread exit |
294 | */ | 299 | */ |
295 | void exit_keys(struct task_struct *tsk) | 300 | void exit_keys(struct task_struct *tsk) |
296 | { | 301 | { |
297 | key_put(tsk->thread_keyring); | 302 | key_put(tsk->thread_keyring); |
303 | key_put(tsk->request_key_auth); | ||
298 | 304 | ||
299 | } /* end exit_keys() */ | 305 | } /* end exit_keys() */ |
300 | 306 | ||
@@ -382,7 +388,7 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
382 | struct task_struct *context) | 388 | struct task_struct *context) |
383 | { | 389 | { |
384 | struct request_key_auth *rka; | 390 | struct request_key_auth *rka; |
385 | key_ref_t key_ref, ret, err, instkey_ref; | 391 | key_ref_t key_ref, ret, err; |
386 | 392 | ||
387 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were | 393 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
388 | * searchable, but we failed to find a key or we found a negative key; | 394 | * searchable, but we failed to find a key or we found a negative key; |
@@ -461,30 +467,12 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
461 | err = key_ref; | 467 | err = key_ref; |
462 | break; | 468 | break; |
463 | } | 469 | } |
464 | 470 | } | |
465 | /* if this process has a session keyring and that has an | 471 | /* or search the user-session keyring */ |
466 | * instantiation authorisation key in the bottom level, then we | 472 | else { |
467 | * also search the keyrings of the process mentioned there */ | 473 | key_ref = keyring_search_aux( |
468 | if (context != current) | 474 | make_key_ref(context->user->session_keyring, 1), |
469 | goto no_key; | 475 | context, type, description, match); |
470 | |||
471 | rcu_read_lock(); | ||
472 | instkey_ref = __keyring_search_one( | ||
473 | make_key_ref(rcu_dereference( | ||
474 | context->signal->session_keyring), | ||
475 | 1), | ||
476 | &key_type_request_key_auth, NULL, 0); | ||
477 | rcu_read_unlock(); | ||
478 | |||
479 | if (IS_ERR(instkey_ref)) | ||
480 | goto no_key; | ||
481 | |||
482 | rka = key_ref_to_ptr(instkey_ref)->payload.data; | ||
483 | |||
484 | key_ref = search_process_keyrings(type, description, match, | ||
485 | rka->context); | ||
486 | key_ref_put(instkey_ref); | ||
487 | |||
488 | if (!IS_ERR(key_ref)) | 476 | if (!IS_ERR(key_ref)) |
489 | goto found; | 477 | goto found; |
490 | 478 | ||
@@ -500,11 +488,21 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
500 | break; | 488 | break; |
501 | } | 489 | } |
502 | } | 490 | } |
503 | /* or search the user-session keyring */ | 491 | |
504 | else { | 492 | /* if this process has an instantiation authorisation key, then we also |
505 | key_ref = keyring_search_aux( | 493 | * search the keyrings of the process mentioned there |
506 | make_key_ref(context->user->session_keyring, 1), | 494 | * - we don't permit access to request_key auth keys via this method |
507 | context, type, description, match); | 495 | */ |
496 | if (context->request_key_auth && | ||
497 | context == current && | ||
498 | type != &key_type_request_key_auth && | ||
499 | key_validate(context->request_key_auth) == 0 | ||
500 | ) { | ||
501 | rka = context->request_key_auth->payload.data; | ||
502 | |||
503 | key_ref = search_process_keyrings(type, description, match, | ||
504 | rka->context); | ||
505 | |||
508 | if (!IS_ERR(key_ref)) | 506 | if (!IS_ERR(key_ref)) |
509 | goto found; | 507 | goto found; |
510 | 508 | ||
@@ -521,8 +519,6 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
521 | } | 519 | } |
522 | } | 520 | } |
523 | 521 | ||
524 | |||
525 | no_key: | ||
526 | /* no key - decide on the error we're going to go for */ | 522 | /* no key - decide on the error we're going to go for */ |
527 | key_ref = ret ? ret : err; | 523 | key_ref = ret ? ret : err; |
528 | 524 | ||
@@ -628,6 +624,15 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, | |||
628 | key = ERR_PTR(-EINVAL); | 624 | key = ERR_PTR(-EINVAL); |
629 | goto error; | 625 | goto error; |
630 | 626 | ||
627 | case KEY_SPEC_REQKEY_AUTH_KEY: | ||
628 | key = context->request_key_auth; | ||
629 | if (!key) | ||
630 | goto error; | ||
631 | |||
632 | atomic_inc(&key->usage); | ||
633 | key_ref = make_key_ref(key, 1); | ||
634 | break; | ||
635 | |||
631 | default: | 636 | default: |
632 | key_ref = ERR_PTR(-EINVAL); | 637 | key_ref = ERR_PTR(-EINVAL); |
633 | if (id < 1) | 638 | if (id < 1) |