aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
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 /include/linux
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 'include/linux')
-rw-r--r--include/linux/cred.h2
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/nsproxy.h1
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/user_namespace.h13
5 files changed, 7 insertions, 11 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 26c1ab179946..3282ee4318e7 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -60,6 +60,7 @@ do { \
60} while (0) 60} while (0)
61 61
62extern struct group_info *groups_alloc(int); 62extern struct group_info *groups_alloc(int);
63extern struct group_info init_groups;
63extern void groups_free(struct group_info *); 64extern void groups_free(struct group_info *);
64extern int set_current_groups(struct group_info *); 65extern int set_current_groups(struct group_info *);
65extern int set_groups(struct cred *, struct group_info *); 66extern int set_groups(struct cred *, struct group_info *);
@@ -315,6 +316,7 @@ static inline void put_cred(const struct cred *_cred)
315#define current_fsgid() (current_cred_xxx(fsgid)) 316#define current_fsgid() (current_cred_xxx(fsgid))
316#define current_cap() (current_cred_xxx(cap_effective)) 317#define current_cap() (current_cred_xxx(cap_effective))
317#define current_user() (current_cred_xxx(user)) 318#define current_user() (current_cred_xxx(user))
319#define current_user_ns() (current_cred_xxx(user)->user_ns)
318#define current_security() (current_cred_xxx(security)) 320#define current_security() (current_cred_xxx(security))
319 321
320#define current_uid_gid(_uid, _gid) \ 322#define current_uid_gid(_uid, _gid) \
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 2597858035cd..959f5522d10a 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -57,7 +57,6 @@ extern struct nsproxy init_nsproxy;
57 .mnt_ns = NULL, \ 57 .mnt_ns = NULL, \
58 INIT_NET_NS(net_ns) \ 58 INIT_NET_NS(net_ns) \
59 INIT_IPC_NS(ipc_ns) \ 59 INIT_IPC_NS(ipc_ns) \
60 .user_ns = &init_user_ns, \
61} 60}
62 61
63#define INIT_SIGHAND(sighand) { \ 62#define INIT_SIGHAND(sighand) { \
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index c8a768e59640..afad7dec1b36 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -27,7 +27,6 @@ struct nsproxy {
27 struct ipc_namespace *ipc_ns; 27 struct ipc_namespace *ipc_ns;
28 struct mnt_namespace *mnt_ns; 28 struct mnt_namespace *mnt_ns;
29 struct pid_namespace *pid_ns; 29 struct pid_namespace *pid_ns;
30 struct user_namespace *user_ns;
31 struct net *net_ns; 30 struct net *net_ns;
32}; 31};
33extern struct nsproxy init_nsproxy; 32extern struct nsproxy init_nsproxy;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2036e9f26020..7f8015a3082e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -638,6 +638,7 @@ struct user_struct {
638 /* Hash table maintenance information */ 638 /* Hash table maintenance information */
639 struct hlist_node uidhash_node; 639 struct hlist_node uidhash_node;
640 uid_t uid; 640 uid_t uid;
641 struct user_namespace *user_ns;
641 642
642#ifdef CONFIG_USER_SCHED 643#ifdef CONFIG_USER_SCHED
643 struct task_group *tg; 644 struct task_group *tg;
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index b5f41d4c2eec..315bcd375224 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -12,7 +12,7 @@
12struct user_namespace { 12struct user_namespace {
13 struct kref kref; 13 struct kref kref;
14 struct hlist_head uidhash_table[UIDHASH_SZ]; 14 struct hlist_head uidhash_table[UIDHASH_SZ];
15 struct user_struct *root_user; 15 struct user_struct *creator;
16}; 16};
17 17
18extern struct user_namespace init_user_ns; 18extern struct user_namespace init_user_ns;
@@ -26,8 +26,7 @@ static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
26 return ns; 26 return ns;
27} 27}
28 28
29extern struct user_namespace *copy_user_ns(int flags, 29extern int create_user_ns(struct cred *new);
30 struct user_namespace *old_ns);
31extern void free_user_ns(struct kref *kref); 30extern void free_user_ns(struct kref *kref);
32 31
33static inline void put_user_ns(struct user_namespace *ns) 32static inline void put_user_ns(struct user_namespace *ns)
@@ -43,13 +42,9 @@ static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
43 return &init_user_ns; 42 return &init_user_ns;
44} 43}
45 44
46static inline struct user_namespace *copy_user_ns(int flags, 45static inline int create_user_ns(struct cred *new)
47 struct user_namespace *old_ns)
48{ 46{
49 if (flags & CLONE_NEWUSER) 47 return -EINVAL;
50 return ERR_PTR(-EINVAL);
51
52 return old_ns;
53} 48}
54 49
55static inline void put_user_ns(struct user_namespace *ns) 50static inline void put_user_ns(struct user_namespace *ns)