diff options
Diffstat (limited to 'kernel/utsname.c')
-rw-r--r-- | kernel/utsname.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/kernel/utsname.c b/kernel/utsname.c index 679d97a5d3fd..08b197e8c485 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c | |||
@@ -32,18 +32,25 @@ static struct uts_namespace *create_uts_ns(void) | |||
32 | * @old_ns: namespace to clone | 32 | * @old_ns: namespace to clone |
33 | * Return NULL on error (failure to kmalloc), new ns otherwise | 33 | * Return NULL on error (failure to kmalloc), new ns otherwise |
34 | */ | 34 | */ |
35 | static struct uts_namespace *clone_uts_ns(struct task_struct *tsk, | 35 | static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns, |
36 | struct uts_namespace *old_ns) | 36 | struct uts_namespace *old_ns) |
37 | { | 37 | { |
38 | struct uts_namespace *ns; | 38 | struct uts_namespace *ns; |
39 | int err; | ||
39 | 40 | ||
40 | ns = create_uts_ns(); | 41 | ns = create_uts_ns(); |
41 | if (!ns) | 42 | if (!ns) |
42 | return ERR_PTR(-ENOMEM); | 43 | return ERR_PTR(-ENOMEM); |
43 | 44 | ||
45 | err = proc_alloc_inum(&ns->proc_inum); | ||
46 | if (err) { | ||
47 | kfree(ns); | ||
48 | return ERR_PTR(err); | ||
49 | } | ||
50 | |||
44 | down_read(&uts_sem); | 51 | down_read(&uts_sem); |
45 | memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); | 52 | memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); |
46 | ns->user_ns = get_user_ns(task_cred_xxx(tsk, user_ns)); | 53 | ns->user_ns = get_user_ns(user_ns); |
47 | up_read(&uts_sem); | 54 | up_read(&uts_sem); |
48 | return ns; | 55 | return ns; |
49 | } | 56 | } |
@@ -55,9 +62,8 @@ static struct uts_namespace *clone_uts_ns(struct task_struct *tsk, | |||
55 | * versa. | 62 | * versa. |
56 | */ | 63 | */ |
57 | struct uts_namespace *copy_utsname(unsigned long flags, | 64 | struct uts_namespace *copy_utsname(unsigned long flags, |
58 | struct task_struct *tsk) | 65 | struct user_namespace *user_ns, struct uts_namespace *old_ns) |
59 | { | 66 | { |
60 | struct uts_namespace *old_ns = tsk->nsproxy->uts_ns; | ||
61 | struct uts_namespace *new_ns; | 67 | struct uts_namespace *new_ns; |
62 | 68 | ||
63 | BUG_ON(!old_ns); | 69 | BUG_ON(!old_ns); |
@@ -66,7 +72,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, | |||
66 | if (!(flags & CLONE_NEWUTS)) | 72 | if (!(flags & CLONE_NEWUTS)) |
67 | return old_ns; | 73 | return old_ns; |
68 | 74 | ||
69 | new_ns = clone_uts_ns(tsk, old_ns); | 75 | new_ns = clone_uts_ns(user_ns, old_ns); |
70 | 76 | ||
71 | put_uts_ns(old_ns); | 77 | put_uts_ns(old_ns); |
72 | return new_ns; | 78 | return new_ns; |
@@ -78,6 +84,7 @@ void free_uts_ns(struct kref *kref) | |||
78 | 84 | ||
79 | ns = container_of(kref, struct uts_namespace, kref); | 85 | ns = container_of(kref, struct uts_namespace, kref); |
80 | put_user_ns(ns->user_ns); | 86 | put_user_ns(ns->user_ns); |
87 | proc_free_inum(ns->proc_inum); | ||
81 | kfree(ns); | 88 | kfree(ns); |
82 | } | 89 | } |
83 | 90 | ||
@@ -102,19 +109,32 @@ static void utsns_put(void *ns) | |||
102 | put_uts_ns(ns); | 109 | put_uts_ns(ns); |
103 | } | 110 | } |
104 | 111 | ||
105 | static int utsns_install(struct nsproxy *nsproxy, void *ns) | 112 | static int utsns_install(struct nsproxy *nsproxy, void *new) |
106 | { | 113 | { |
114 | struct uts_namespace *ns = new; | ||
115 | |||
116 | if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || | ||
117 | !nsown_capable(CAP_SYS_ADMIN)) | ||
118 | return -EPERM; | ||
119 | |||
107 | get_uts_ns(ns); | 120 | get_uts_ns(ns); |
108 | put_uts_ns(nsproxy->uts_ns); | 121 | put_uts_ns(nsproxy->uts_ns); |
109 | nsproxy->uts_ns = ns; | 122 | nsproxy->uts_ns = ns; |
110 | return 0; | 123 | return 0; |
111 | } | 124 | } |
112 | 125 | ||
126 | static unsigned int utsns_inum(void *vp) | ||
127 | { | ||
128 | struct uts_namespace *ns = vp; | ||
129 | |||
130 | return ns->proc_inum; | ||
131 | } | ||
132 | |||
113 | const struct proc_ns_operations utsns_operations = { | 133 | const struct proc_ns_operations utsns_operations = { |
114 | .name = "uts", | 134 | .name = "uts", |
115 | .type = CLONE_NEWUTS, | 135 | .type = CLONE_NEWUTS, |
116 | .get = utsns_get, | 136 | .get = utsns_get, |
117 | .put = utsns_put, | 137 | .put = utsns_put, |
118 | .install = utsns_install, | 138 | .install = utsns_install, |
139 | .inum = utsns_inum, | ||
119 | }; | 140 | }; |
120 | |||