diff options
-rw-r--r-- | include/linux/utsname.h | 4 | ||||
-rw-r--r-- | init/version.c | 1 | ||||
-rw-r--r-- | kernel/nsproxy.c | 5 | ||||
-rw-r--r-- | kernel/user.c | 8 | ||||
-rw-r--r-- | kernel/utsname.c | 4 |
5 files changed, 20 insertions, 2 deletions
diff --git a/include/linux/utsname.h b/include/linux/utsname.h index 69f39974c041..2c3c0f543705 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h | |||
@@ -37,9 +37,13 @@ struct new_utsname { | |||
37 | #include <linux/nsproxy.h> | 37 | #include <linux/nsproxy.h> |
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | 39 | ||
40 | struct user_namespace; | ||
41 | extern struct user_namespace init_user_ns; | ||
42 | |||
40 | struct uts_namespace { | 43 | struct uts_namespace { |
41 | struct kref kref; | 44 | struct kref kref; |
42 | struct new_utsname name; | 45 | struct new_utsname name; |
46 | struct user_namespace *user_ns; | ||
43 | }; | 47 | }; |
44 | extern struct uts_namespace init_uts_ns; | 48 | extern struct uts_namespace init_uts_ns; |
45 | 49 | ||
diff --git a/init/version.c b/init/version.c index adff586401a5..86fe0ccb997a 100644 --- a/init/version.c +++ b/init/version.c | |||
@@ -33,6 +33,7 @@ struct uts_namespace init_uts_ns = { | |||
33 | .machine = UTS_MACHINE, | 33 | .machine = UTS_MACHINE, |
34 | .domainname = UTS_DOMAINNAME, | 34 | .domainname = UTS_DOMAINNAME, |
35 | }, | 35 | }, |
36 | .user_ns = &init_user_ns, | ||
36 | }; | 37 | }; |
37 | EXPORT_SYMBOL_GPL(init_uts_ns); | 38 | EXPORT_SYMBOL_GPL(init_uts_ns); |
38 | 39 | ||
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index f74e6c00e26d..034dc2ed13ac 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -74,6 +74,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, | |||
74 | err = PTR_ERR(new_nsp->uts_ns); | 74 | err = PTR_ERR(new_nsp->uts_ns); |
75 | goto out_uts; | 75 | goto out_uts; |
76 | } | 76 | } |
77 | if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { | ||
78 | put_user_ns(new_nsp->uts_ns->user_ns); | ||
79 | new_nsp->uts_ns->user_ns = task_cred_xxx(tsk, user)->user_ns; | ||
80 | get_user_ns(new_nsp->uts_ns->user_ns); | ||
81 | } | ||
77 | 82 | ||
78 | new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns); | 83 | new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns); |
79 | if (IS_ERR(new_nsp->ipc_ns)) { | 84 | if (IS_ERR(new_nsp->ipc_ns)) { |
diff --git a/kernel/user.c b/kernel/user.c index 5c598ca781df..9e03e9c1df8d 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
@@ -17,9 +17,13 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/user_namespace.h> | 18 | #include <linux/user_namespace.h> |
19 | 19 | ||
20 | /* | ||
21 | * userns count is 1 for root user, 1 for init_uts_ns, | ||
22 | * and 1 for... ? | ||
23 | */ | ||
20 | struct user_namespace init_user_ns = { | 24 | struct user_namespace init_user_ns = { |
21 | .kref = { | 25 | .kref = { |
22 | .refcount = ATOMIC_INIT(2), | 26 | .refcount = ATOMIC_INIT(3), |
23 | }, | 27 | }, |
24 | .creator = &root_user, | 28 | .creator = &root_user, |
25 | }; | 29 | }; |
@@ -47,7 +51,7 @@ static struct kmem_cache *uid_cachep; | |||
47 | */ | 51 | */ |
48 | static DEFINE_SPINLOCK(uidhash_lock); | 52 | static DEFINE_SPINLOCK(uidhash_lock); |
49 | 53 | ||
50 | /* root_user.__count is 2, 1 for init task cred, 1 for init_user_ns->creator */ | 54 | /* root_user.__count is 2, 1 for init task cred, 1 for init_user_ns->user_ns */ |
51 | struct user_struct root_user = { | 55 | struct user_struct root_user = { |
52 | .__count = ATOMIC_INIT(2), | 56 | .__count = ATOMIC_INIT(2), |
53 | .processes = ATOMIC_INIT(1), | 57 | .processes = ATOMIC_INIT(1), |
diff --git a/kernel/utsname.c b/kernel/utsname.c index 8a82b4b8ea52..a7b3a8d1ad24 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/utsname.h> | 14 | #include <linux/utsname.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/user_namespace.h> | ||
17 | 18 | ||
18 | static struct uts_namespace *create_uts_ns(void) | 19 | static struct uts_namespace *create_uts_ns(void) |
19 | { | 20 | { |
@@ -40,6 +41,8 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns) | |||
40 | 41 | ||
41 | down_read(&uts_sem); | 42 | down_read(&uts_sem); |
42 | memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); | 43 | memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); |
44 | ns->user_ns = old_ns->user_ns; | ||
45 | get_user_ns(ns->user_ns); | ||
43 | up_read(&uts_sem); | 46 | up_read(&uts_sem); |
44 | return ns; | 47 | return ns; |
45 | } | 48 | } |
@@ -71,5 +74,6 @@ void free_uts_ns(struct kref *kref) | |||
71 | struct uts_namespace *ns; | 74 | struct uts_namespace *ns; |
72 | 75 | ||
73 | ns = container_of(kref, struct uts_namespace, kref); | 76 | ns = container_of(kref, struct uts_namespace, kref); |
77 | put_user_ns(ns->user_ns); | ||
74 | kfree(ns); | 78 | kfree(ns); |
75 | } | 79 | } |