aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/process_keys.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /security/keys/process_keys.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r--security/keys/process_keys.c150
1 files changed, 89 insertions, 61 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index f8e7251ae2c8..a3063eb3dc23 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 */
25static DEFINE_MUTEX(key_session_mutex); 25static DEFINE_MUTEX(key_session_mutex);
26 26
27/* user keyring creation semaphore */ 27/* User keyring creation semaphore */
28static DEFINE_MUTEX(key_user_keyring_mutex); 28static DEFINE_MUTEX(key_user_keyring_mutex);
29 29
30/* the root user's tracking struct */ 30/* The root user's tracking struct */
31struct key_user root_key_user = { 31struct 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 */
45int install_user_keyrings(void) 44int 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 */
127int install_thread_keyring_to_cred(struct cred *new) 127int 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 */
143static int install_thread_keyring(void) 143static 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 */
168int install_process_keyring_to_cred(struct cred *new) 169int 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 */
198static int install_process_keyring(void) 202static int install_process_keyring(void)
199{ 203{
@@ -207,14 +211,14 @@ static int install_process_keyring(void)
207 ret = install_process_keyring_to_cred(new); 211 ret = install_process_keyring_to_cred(new);
208 if (ret < 0) { 212 if (ret < 0) {
209 abort_creds(new); 213 abort_creds(new);
210 return ret != -EEXIST ?: 0; 214 return ret != -EEXIST ? ret : 0;
211 } 215 }
212 216
213 return commit_creds(new); 217 return commit_creds(new);
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 */
219int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) 223int 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 */
260static int install_session_keyring(struct key *keyring) 264static 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 */
282void key_fsuid_changed(struct task_struct *tsk) 285void 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 */
298void key_fsgid_changed(struct task_struct *tsk) 299void key_fsgid_changed(struct task_struct *tsk)
299{ 300{
@@ -304,20 +305,33 @@ 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 */
318key_ref_t search_my_process_keyrings(struct key_type *type, 331key_ref_t search_my_process_keyrings(struct key_type *type,
319 const void *description, 332 const void *description,
320 key_match_func_t match, 333 key_match_func_t match,
334 bool no_state_check,
321 const struct cred *cred) 335 const struct cred *cred)
322{ 336{
323 key_ref_t key_ref, ret, err; 337 key_ref_t key_ref, ret, err;
@@ -337,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
337 if (cred->thread_keyring) { 351 if (cred->thread_keyring) {
338 key_ref = keyring_search_aux( 352 key_ref = keyring_search_aux(
339 make_key_ref(cred->thread_keyring, 1), 353 make_key_ref(cred->thread_keyring, 1),
340 cred, type, description, match); 354 cred, type, description, match, no_state_check);
341 if (!IS_ERR(key_ref)) 355 if (!IS_ERR(key_ref))
342 goto found; 356 goto found;
343 357
@@ -358,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
358 if (cred->tgcred->process_keyring) { 372 if (cred->tgcred->process_keyring) {
359 key_ref = keyring_search_aux( 373 key_ref = keyring_search_aux(
360 make_key_ref(cred->tgcred->process_keyring, 1), 374 make_key_ref(cred->tgcred->process_keyring, 1),
361 cred, type, description, match); 375 cred, type, description, match, no_state_check);
362 if (!IS_ERR(key_ref)) 376 if (!IS_ERR(key_ref))
363 goto found; 377 goto found;
364 378
@@ -382,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
382 make_key_ref(rcu_dereference( 396 make_key_ref(rcu_dereference(
383 cred->tgcred->session_keyring), 397 cred->tgcred->session_keyring),
384 1), 398 1),
385 cred, type, description, match); 399 cred, type, description, match, no_state_check);
386 rcu_read_unlock(); 400 rcu_read_unlock();
387 401
388 if (!IS_ERR(key_ref)) 402 if (!IS_ERR(key_ref))
@@ -404,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
404 else if (cred->user->session_keyring) { 418 else if (cred->user->session_keyring) {
405 key_ref = keyring_search_aux( 419 key_ref = keyring_search_aux(
406 make_key_ref(cred->user->session_keyring, 1), 420 make_key_ref(cred->user->session_keyring, 1),
407 cred, type, description, match); 421 cred, type, description, match, no_state_check);
408 if (!IS_ERR(key_ref)) 422 if (!IS_ERR(key_ref))
409 goto found; 423 goto found;
410 424
@@ -428,13 +442,13 @@ found:
428 return key_ref; 442 return key_ref;
429} 443}
430 444
431/*****************************************************************************/
432/* 445/*
433 * search the process keyrings for the first matching key 446 * 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 447 * matching key in the manner of search_my_process_keyrings(), but also search
435 * feature of interest) matches 448 * the keys attached to the assumed authorisation key using its credentials if
436 * - we return -EAGAIN if we didn't find any matching key 449 * one is available.
437 * - we return -ENOKEY if we found only negative matching keys 450 *
451 * Return same as search_my_process_keyrings().
438 */ 452 */
439key_ref_t search_process_keyrings(struct key_type *type, 453key_ref_t search_process_keyrings(struct key_type *type,
440 const void *description, 454 const void *description,
@@ -446,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
446 460
447 might_sleep(); 461 might_sleep();
448 462
449 key_ref = search_my_process_keyrings(type, description, match, cred); 463 key_ref = search_my_process_keyrings(type, description, match,
464 false, cred);
450 if (!IS_ERR(key_ref)) 465 if (!IS_ERR(key_ref))
451 goto found; 466 goto found;
452 err = key_ref; 467 err = key_ref;
@@ -489,24 +504,33 @@ key_ref_t search_process_keyrings(struct key_type *type,
489 504
490found: 505found:
491 return key_ref; 506 return key_ref;
507}
492 508
493} /* end search_process_keyrings() */
494
495/*****************************************************************************/
496/* 509/*
497 * see if the key we're looking at is the target key 510 * See if the key we're looking at is the target key.
498 */ 511 */
499int lookup_user_key_possessed(const struct key *key, const void *target) 512int lookup_user_key_possessed(const struct key *key, const void *target)
500{ 513{
501 return key == target; 514 return key == target;
515}
502 516
503} /* end lookup_user_key_possessed() */
504
505/*****************************************************************************/
506/* 517/*
507 * lookup a key given a key ID from userspace with a given permissions mask 518 * 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 519 * the key it refers to.
509 * - partially constructed keys aren't found unless requested 520 *
521 * Flags can be passed to request that special keyrings be created if referred
522 * to directly, to permit partially constructed keys to be found and to skip
523 * validity and permission checks on the found key.
524 *
525 * Returns a pointer to the key with an incremented usage count if successful;
526 * -EINVAL if the key ID is invalid; -ENOKEY if the key ID does not correspond
527 * to a key or the best found key was a negative key; -EKEYREVOKED or
528 * -EKEYEXPIRED if the best found key was revoked or expired; -EACCES if the
529 * found key doesn't grant the requested permit or the LSM denied access to it;
530 * or -ENOMEM if a special keyring couldn't be created.
531 *
532 * In the case of a successful return, the possession attribute is set on the
533 * returned key reference.
510 */ 534 */
511key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, 535key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
512 key_perm_t perm) 536 key_perm_t perm)
@@ -711,15 +735,18 @@ invalid_key:
711reget_creds: 735reget_creds:
712 put_cred(cred); 736 put_cred(cred);
713 goto try_again; 737 goto try_again;
738}
714 739
715} /* end lookup_user_key() */
716
717/*****************************************************************************/
718/* 740/*
719 * join the named keyring as the session keyring if possible, or attempt to 741 * Join the named keyring as the session keyring if possible else attempt to
720 * create a new one of that name if not 742 * create a new one of that name and join that.
721 * - if the name is NULL, an empty anonymous keyring is installed instead 743 *
722 * - named session keyring joining is done with a semaphore held 744 * If the name is NULL, an empty anonymous keyring will be installed as the
745 * session keyring.
746 *
747 * Named session keyrings are joined with a semaphore held to prevent the
748 * keyrings from going away whilst the attempt is made to going them and also
749 * to prevent a race in creating compatible session keyrings.
723 */ 750 */
724long join_session_keyring(const char *name) 751long join_session_keyring(const char *name)
725{ 752{
@@ -791,8 +818,8 @@ error:
791} 818}
792 819
793/* 820/*
794 * Replace a process's session keyring when that process resumes userspace on 821 * Replace a process's session keyring on behalf of one of its children when
795 * behalf of one of its children 822 * the target process is about to resume userspace execution.
796 */ 823 */
797void key_replace_session_keyring(void) 824void key_replace_session_keyring(void)
798{ 825{
@@ -820,6 +847,7 @@ void key_replace_session_keyring(void)
820 new-> sgid = old-> sgid; 847 new-> sgid = old-> sgid;
821 new->fsgid = old->fsgid; 848 new->fsgid = old->fsgid;
822 new->user = get_uid(old->user); 849 new->user = get_uid(old->user);
850 new->user_ns = new->user->user_ns;
823 new->group_info = get_group_info(old->group_info); 851 new->group_info = get_group_info(old->group_info);
824 852
825 new->securebits = old->securebits; 853 new->securebits = old->securebits;