diff options
Diffstat (limited to 'security/keys/process_keys.c')
| -rw-r--r-- | security/keys/process_keys.c | 135 |
1 files changed, 80 insertions, 55 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 504bdd2452bd..930634e45149 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Management of a process's keyrings | 1 | /* Manage a process's keyrings |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved. |
| 4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
| @@ -21,13 +21,13 @@ | |||
| 21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| 22 | #include "internal.h" | 22 | #include "internal.h" |
| 23 | 23 | ||
| 24 | /* session keyring create vs join semaphore */ | 24 | /* Session keyring create vs join semaphore */ |
| 25 | static DEFINE_MUTEX(key_session_mutex); | 25 | static DEFINE_MUTEX(key_session_mutex); |
| 26 | 26 | ||
| 27 | /* user keyring creation semaphore */ | 27 | /* User keyring creation semaphore */ |
| 28 | static DEFINE_MUTEX(key_user_keyring_mutex); | 28 | static DEFINE_MUTEX(key_user_keyring_mutex); |
| 29 | 29 | ||
| 30 | /* the root user's tracking struct */ | 30 | /* The root user's tracking struct */ |
| 31 | struct key_user root_key_user = { | 31 | struct key_user root_key_user = { |
| 32 | .usage = ATOMIC_INIT(3), | 32 | .usage = ATOMIC_INIT(3), |
| 33 | .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock), | 33 | .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock), |
| @@ -38,9 +38,8 @@ struct key_user root_key_user = { | |||
| 38 | .user_ns = &init_user_ns, | 38 | .user_ns = &init_user_ns, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | /*****************************************************************************/ | ||
| 42 | /* | 41 | /* |
| 43 | * install user and user session keyrings for a particular UID | 42 | * Install the user and user session keyrings for the current process's UID. |
| 44 | */ | 43 | */ |
| 45 | int install_user_keyrings(void) | 44 | int install_user_keyrings(void) |
| 46 | { | 45 | { |
| @@ -122,7 +121,8 @@ error: | |||
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | /* | 123 | /* |
| 125 | * install a fresh thread keyring directly to new credentials | 124 | * Install a fresh thread keyring directly to new credentials. This keyring is |
| 125 | * allowed to overrun the quota. | ||
| 126 | */ | 126 | */ |
| 127 | int install_thread_keyring_to_cred(struct cred *new) | 127 | int install_thread_keyring_to_cred(struct cred *new) |
| 128 | { | 128 | { |
| @@ -138,7 +138,7 @@ int install_thread_keyring_to_cred(struct cred *new) | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /* | 140 | /* |
| 141 | * install a fresh thread keyring, discarding the old one | 141 | * Install a fresh thread keyring, discarding the old one. |
| 142 | */ | 142 | */ |
| 143 | static int install_thread_keyring(void) | 143 | static int install_thread_keyring(void) |
| 144 | { | 144 | { |
| @@ -161,9 +161,10 @@ static int install_thread_keyring(void) | |||
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| 164 | * install a process keyring directly to a credentials struct | 164 | * Install a process keyring directly to a credentials struct. |
| 165 | * - returns -EEXIST if there was already a process keyring, 0 if one installed, | 165 | * |
| 166 | * and other -ve on any other error | 166 | * Returns -EEXIST if there was already a process keyring, 0 if one installed, |
| 167 | * and other value on any other error | ||
| 167 | */ | 168 | */ |
| 168 | int install_process_keyring_to_cred(struct cred *new) | 169 | int install_process_keyring_to_cred(struct cred *new) |
| 169 | { | 170 | { |
| @@ -192,8 +193,11 @@ int install_process_keyring_to_cred(struct cred *new) | |||
| 192 | } | 193 | } |
| 193 | 194 | ||
| 194 | /* | 195 | /* |
| 195 | * make sure a process keyring is installed | 196 | * Make sure a process keyring is installed for the current process. The |
| 196 | * - we | 197 | * existing process keyring is not replaced. |
| 198 | * | ||
| 199 | * Returns 0 if there is a process keyring by the end of this function, some | ||
| 200 | * error otherwise. | ||
| 197 | */ | 201 | */ |
| 198 | static int install_process_keyring(void) | 202 | static int install_process_keyring(void) |
| 199 | { | 203 | { |
| @@ -214,7 +218,7 @@ static int install_process_keyring(void) | |||
| 214 | } | 218 | } |
| 215 | 219 | ||
| 216 | /* | 220 | /* |
| 217 | * install a session keyring directly to a credentials struct | 221 | * Install a session keyring directly to a credentials struct. |
| 218 | */ | 222 | */ |
| 219 | int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) | 223 | int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) |
| 220 | { | 224 | { |
| @@ -254,8 +258,8 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) | |||
| 254 | } | 258 | } |
| 255 | 259 | ||
| 256 | /* | 260 | /* |
| 257 | * install a session keyring, discarding the old one | 261 | * Install a session keyring, discarding the old one. If a keyring is not |
| 258 | * - if a keyring is not supplied, an empty one is invented | 262 | * supplied, an empty one is invented. |
| 259 | */ | 263 | */ |
| 260 | static int install_session_keyring(struct key *keyring) | 264 | static int install_session_keyring(struct key *keyring) |
| 261 | { | 265 | { |
| @@ -275,9 +279,8 @@ static int install_session_keyring(struct key *keyring) | |||
| 275 | return commit_creds(new); | 279 | return commit_creds(new); |
| 276 | } | 280 | } |
| 277 | 281 | ||
| 278 | /*****************************************************************************/ | ||
| 279 | /* | 282 | /* |
| 280 | * the filesystem user ID changed | 283 | * Handle the fsuid changing. |
| 281 | */ | 284 | */ |
| 282 | void key_fsuid_changed(struct task_struct *tsk) | 285 | void key_fsuid_changed(struct task_struct *tsk) |
| 283 | { | 286 | { |
| @@ -288,12 +291,10 @@ void key_fsuid_changed(struct task_struct *tsk) | |||
| 288 | tsk->cred->thread_keyring->uid = tsk->cred->fsuid; | 291 | tsk->cred->thread_keyring->uid = tsk->cred->fsuid; |
| 289 | up_write(&tsk->cred->thread_keyring->sem); | 292 | up_write(&tsk->cred->thread_keyring->sem); |
| 290 | } | 293 | } |
| 294 | } | ||
| 291 | 295 | ||
| 292 | } /* end key_fsuid_changed() */ | ||
| 293 | |||
| 294 | /*****************************************************************************/ | ||
| 295 | /* | 296 | /* |
| 296 | * the filesystem group ID changed | 297 | * Handle the fsgid changing. |
| 297 | */ | 298 | */ |
| 298 | void key_fsgid_changed(struct task_struct *tsk) | 299 | void key_fsgid_changed(struct task_struct *tsk) |
| 299 | { | 300 | { |
| @@ -304,16 +305,28 @@ void key_fsgid_changed(struct task_struct *tsk) | |||
| 304 | tsk->cred->thread_keyring->gid = tsk->cred->fsgid; | 305 | tsk->cred->thread_keyring->gid = tsk->cred->fsgid; |
| 305 | up_write(&tsk->cred->thread_keyring->sem); | 306 | up_write(&tsk->cred->thread_keyring->sem); |
| 306 | } | 307 | } |
| 308 | } | ||
| 307 | 309 | ||
| 308 | } /* end key_fsgid_changed() */ | ||
| 309 | |||
| 310 | /*****************************************************************************/ | ||
| 311 | /* | 310 | /* |
| 312 | * search only my process keyrings for the first matching key | 311 | * Search the process keyrings attached to the supplied cred for the first |
| 313 | * - we use the supplied match function to see if the description (or other | 312 | * matching key. |
| 314 | * feature of interest) matches | 313 | * |
| 315 | * - we return -EAGAIN if we didn't find any matching key | 314 | * The search criteria are the type and the match function. The description is |
| 316 | * - we return -ENOKEY if we found only negative matching keys | 315 | * given to the match function as a parameter, but doesn't otherwise influence |
| 316 | * the search. Typically the match function will compare the description | ||
| 317 | * parameter to the key's description. | ||
| 318 | * | ||
| 319 | * This can only search keyrings that grant Search permission to the supplied | ||
| 320 | * credentials. Keyrings linked to searched keyrings will also be searched if | ||
| 321 | * they grant Search permission too. Keys can only be found if they grant | ||
| 322 | * Search permission to the credentials. | ||
| 323 | * | ||
| 324 | * Returns a pointer to the key with the key usage count incremented if | ||
| 325 | * successful, -EAGAIN if we didn't find any matching key or -ENOKEY if we only | ||
| 326 | * matched negative keys. | ||
| 327 | * | ||
| 328 | * In the case of a successful return, the possession attribute is set on the | ||
| 329 | * returned key reference. | ||
| 317 | */ | 330 | */ |
| 318 | key_ref_t search_my_process_keyrings(struct key_type *type, | 331 | key_ref_t search_my_process_keyrings(struct key_type *type, |
| 319 | const void *description, | 332 | const void *description, |
| @@ -428,13 +441,13 @@ found: | |||
| 428 | return key_ref; | 441 | return key_ref; |
| 429 | } | 442 | } |
| 430 | 443 | ||
| 431 | /*****************************************************************************/ | ||
| 432 | /* | 444 | /* |
| 433 | * search the process keyrings for the first matching key | 445 | * Search the process keyrings attached to the supplied cred for the first |
| 434 | * - we use the supplied match function to see if the description (or other | 446 | * matching key in the manner of search_my_process_keyrings(), but also search |
| 435 | * feature of interest) matches | 447 | * the keys attached to the assumed authorisation key using its credentials if |
| 436 | * - we return -EAGAIN if we didn't find any matching key | 448 | * one is available. |
| 437 | * - we return -ENOKEY if we found only negative matching keys | 449 | * |
| 450 | * Return same as search_my_process_keyrings(). | ||
| 438 | */ | 451 | */ |
| 439 | key_ref_t search_process_keyrings(struct key_type *type, | 452 | key_ref_t search_process_keyrings(struct key_type *type, |
| 440 | const void *description, | 453 | const void *description, |
| @@ -489,24 +502,33 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
| 489 | 502 | ||
| 490 | found: | 503 | found: |
| 491 | return key_ref; | 504 | return key_ref; |
| 505 | } | ||
| 492 | 506 | ||
| 493 | } /* end search_process_keyrings() */ | ||
| 494 | |||
| 495 | /*****************************************************************************/ | ||
| 496 | /* | 507 | /* |
| 497 | * see if the key we're looking at is the target key | 508 | * See if the key we're looking at is the target key. |
| 498 | */ | 509 | */ |
| 499 | int lookup_user_key_possessed(const struct key *key, const void *target) | 510 | int lookup_user_key_possessed(const struct key *key, const void *target) |
| 500 | { | 511 | { |
| 501 | return key == target; | 512 | return key == target; |
| 513 | } | ||
| 502 | 514 | ||
| 503 | } /* end lookup_user_key_possessed() */ | ||
| 504 | |||
| 505 | /*****************************************************************************/ | ||
| 506 | /* | 515 | /* |
| 507 | * lookup a key given a key ID from userspace with a given permissions mask | 516 | * Look up a key ID given us by userspace with a given permissions mask to get |
| 508 | * - don't create special keyrings unless so requested | 517 | * the key it refers to. |
| 509 | * - partially constructed keys aren't found unless requested | 518 | * |
| 519 | * Flags can be passed to request that special keyrings be created if referred | ||
| 520 | * to directly, to permit partially constructed keys to be found and to skip | ||
| 521 | * validity and permission checks on the found key. | ||
| 522 | * | ||
| 523 | * Returns a pointer to the key with an incremented usage count if successful; | ||
| 524 | * -EINVAL if the key ID is invalid; -ENOKEY if the key ID does not correspond | ||
| 525 | * to a key or the best found key was a negative key; -EKEYREVOKED or | ||
| 526 | * -EKEYEXPIRED if the best found key was revoked or expired; -EACCES if the | ||
| 527 | * found key doesn't grant the requested permit or the LSM denied access to it; | ||
| 528 | * or -ENOMEM if a special keyring couldn't be created. | ||
| 529 | * | ||
| 530 | * In the case of a successful return, the possession attribute is set on the | ||
| 531 | * returned key reference. | ||
| 510 | */ | 532 | */ |
| 511 | key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, | 533 | key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, |
| 512 | key_perm_t perm) | 534 | key_perm_t perm) |
| @@ -711,15 +733,18 @@ invalid_key: | |||
| 711 | reget_creds: | 733 | reget_creds: |
| 712 | put_cred(cred); | 734 | put_cred(cred); |
| 713 | goto try_again; | 735 | goto try_again; |
| 736 | } | ||
| 714 | 737 | ||
| 715 | } /* end lookup_user_key() */ | ||
| 716 | |||
| 717 | /*****************************************************************************/ | ||
| 718 | /* | 738 | /* |
| 719 | * join the named keyring as the session keyring if possible, or attempt to | 739 | * Join the named keyring as the session keyring if possible else attempt to |
| 720 | * create a new one of that name if not | 740 | * create a new one of that name and join that. |
| 721 | * - if the name is NULL, an empty anonymous keyring is installed instead | 741 | * |
| 722 | * - named session keyring joining is done with a semaphore held | 742 | * If the name is NULL, an empty anonymous keyring will be installed as the |
| 743 | * session keyring. | ||
| 744 | * | ||
| 745 | * Named session keyrings are joined with a semaphore held to prevent the | ||
| 746 | * keyrings from going away whilst the attempt is made to going them and also | ||
| 747 | * to prevent a race in creating compatible session keyrings. | ||
| 723 | */ | 748 | */ |
| 724 | long join_session_keyring(const char *name) | 749 | long join_session_keyring(const char *name) |
| 725 | { | 750 | { |
| @@ -791,8 +816,8 @@ error: | |||
| 791 | } | 816 | } |
| 792 | 817 | ||
| 793 | /* | 818 | /* |
| 794 | * Replace a process's session keyring when that process resumes userspace on | 819 | * Replace a process's session keyring on behalf of one of its children when |
| 795 | * behalf of one of its children | 820 | * the target process is about to resume userspace execution. |
| 796 | */ | 821 | */ |
| 797 | void key_replace_session_keyring(void) | 822 | void key_replace_session_keyring(void) |
| 798 | { | 823 | { |
