aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorSerge Hallyn <serue@us.ibm.com>2008-10-15 17:38:45 -0400
committerSerge E. Hallyn <serue@us.ibm.com>2008-11-24 18:57:41 -0500
commit18b6e0414e42d95183f07d8177e3ff0241abd825 (patch)
tree91ca2f2d442055e31eb7bb551bf7060f3f4c4cc7 /kernel/fork.c
parent9789cfe22e5d7bc10cad841a4ea96ecedb34b267 (diff)
User namespaces: set of cleanups (v2)
The user_ns is moved from nsproxy to user_struct, so that a struct cred by itself is sufficient to determine access (which it otherwise would not be). Corresponding ecryptfs fixes (by David Howells) are here as well. Fix refcounting. The following rules now apply: 1. The task pins the user struct. 2. The user struct pins its user namespace. 3. The user namespace pins the struct user which created it. User namespaces are cloned during copy_creds(). Unsharing a new user_ns is no longer possible. (We could re-add that, but it'll cause code duplication and doesn't seem useful if PAM doesn't need to clone user namespaces). When a user namespace is created, its first user (uid 0) gets empty keyrings and a clean group_info. This incorporates a previous patch by David Howells. Here is his original patch description: >I suggest adding the attached incremental patch. It makes the following >changes: > > (1) Provides a current_user_ns() macro to wrap accesses to current's user > namespace. > > (2) Fixes eCryptFS. > > (3) Renames create_new_userns() to create_user_ns() to be more consistent > with the other associated functions and because the 'new' in the name is > superfluous. > > (4) Moves the argument and permission checks made for CLONE_NEWUSER to the > beginning of do_fork() so that they're done prior to making any attempts > at allocation. > > (5) Calls create_user_ns() after prepare_creds(), and gives it the new creds > to fill in rather than have it return the new root user. I don't imagine > the new root user being used for anything other than filling in a cred > struct. > > This also permits me to get rid of a get_uid() and a free_uid(), as the > reference the creds were holding on the old user_struct can just be > transferred to the new namespace's creator pointer. > > (6) Makes create_user_ns() reset the UIDs and GIDs of the creds under > preparation rather than doing it in copy_creds(). > >David >Signed-off-by: David Howells <dhowells@redhat.com> Changelog: Oct 20: integrate dhowells comments 1. leave thread_keyring alone 2. use current_user_ns() in set_user() Signed-off-by: Serge Hallyn <serue@us.ibm.com>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 29c18c14812d..1dd89451fae4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -976,7 +976,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
976 if (atomic_read(&p->real_cred->user->processes) >= 976 if (atomic_read(&p->real_cred->user->processes) >=
977 p->signal->rlim[RLIMIT_NPROC].rlim_cur) { 977 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
978 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && 978 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
979 p->real_cred->user != current->nsproxy->user_ns->root_user) 979 p->real_cred->user != INIT_USER)
980 goto bad_fork_free; 980 goto bad_fork_free;
981 } 981 }
982 982
@@ -1335,6 +1335,20 @@ long do_fork(unsigned long clone_flags,
1335 long nr; 1335 long nr;
1336 1336
1337 /* 1337 /*
1338 * Do some preliminary argument and permissions checking before we
1339 * actually start allocating stuff
1340 */
1341 if (clone_flags & CLONE_NEWUSER) {
1342 if (clone_flags & CLONE_THREAD)
1343 return -EINVAL;
1344 /* hopefully this check will go away when userns support is
1345 * complete
1346 */
1347 if (!capable(CAP_SYS_ADMIN))
1348 return -EPERM;
1349 }
1350
1351 /*
1338 * We hope to recycle these flags after 2.6.26 1352 * We hope to recycle these flags after 2.6.26
1339 */ 1353 */
1340 if (unlikely(clone_flags & CLONE_STOPPED)) { 1354 if (unlikely(clone_flags & CLONE_STOPPED)) {
@@ -1581,8 +1595,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1581 err = -EINVAL; 1595 err = -EINVAL;
1582 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1596 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1583 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| 1597 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
1584 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| 1598 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET))
1585 CLONE_NEWNET))
1586 goto bad_unshare_out; 1599 goto bad_unshare_out;
1587 1600
1588 /* 1601 /*