Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /*
3 : * Copyright (C) 2004 IBM Corporation
4 : *
5 : * Author: Serge Hallyn <serue@us.ibm.com>
6 : */
7 :
8 : #include <linux/export.h>
9 : #include <linux/uts.h>
10 : #include <linux/utsname.h>
11 : #include <linux/err.h>
12 : #include <linux/slab.h>
13 : #include <linux/cred.h>
14 : #include <linux/user_namespace.h>
15 : #include <linux/proc_ns.h>
16 : #include <linux/sched/task.h>
17 :
18 : static struct kmem_cache *uts_ns_cache __ro_after_init;
19 :
20 : static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
21 : {
22 0 : return inc_ucount(ns, current_euid(), UCOUNT_UTS_NAMESPACES);
23 : }
24 :
25 : static void dec_uts_namespaces(struct ucounts *ucounts)
26 : {
27 0 : dec_ucount(ucounts, UCOUNT_UTS_NAMESPACES);
28 : }
29 :
30 : static struct uts_namespace *create_uts_ns(void)
31 : {
32 : struct uts_namespace *uts_ns;
33 :
34 0 : uts_ns = kmem_cache_alloc(uts_ns_cache, GFP_KERNEL);
35 0 : if (uts_ns)
36 0 : refcount_set(&uts_ns->ns.count, 1);
37 : return uts_ns;
38 : }
39 :
40 : /*
41 : * Clone a new ns copying an original utsname, setting refcount to 1
42 : * @old_ns: namespace to clone
43 : * Return ERR_PTR(-ENOMEM) on error (failure to allocate), new ns otherwise
44 : */
45 0 : static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
46 : struct uts_namespace *old_ns)
47 : {
48 : struct uts_namespace *ns;
49 : struct ucounts *ucounts;
50 : int err;
51 :
52 0 : err = -ENOSPC;
53 0 : ucounts = inc_uts_namespaces(user_ns);
54 0 : if (!ucounts)
55 : goto fail;
56 :
57 0 : err = -ENOMEM;
58 0 : ns = create_uts_ns();
59 0 : if (!ns)
60 : goto fail_dec;
61 :
62 0 : err = ns_alloc_inum(&ns->ns);
63 0 : if (err)
64 : goto fail_free;
65 :
66 0 : ns->ucounts = ucounts;
67 0 : ns->ns.ops = &utsns_operations;
68 :
69 0 : down_read(&uts_sem);
70 0 : memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
71 0 : ns->user_ns = get_user_ns(user_ns);
72 0 : up_read(&uts_sem);
73 0 : return ns;
74 :
75 : fail_free:
76 0 : kmem_cache_free(uts_ns_cache, ns);
77 : fail_dec:
78 : dec_uts_namespaces(ucounts);
79 : fail:
80 0 : return ERR_PTR(err);
81 : }
82 :
83 : /*
84 : * Copy task tsk's utsname namespace, or clone it if flags
85 : * specifies CLONE_NEWUTS. In latter case, changes to the
86 : * utsname of this process won't be seen by parent, and vice
87 : * versa.
88 : */
89 0 : struct uts_namespace *copy_utsname(unsigned long flags,
90 : struct user_namespace *user_ns, struct uts_namespace *old_ns)
91 : {
92 : struct uts_namespace *new_ns;
93 :
94 0 : BUG_ON(!old_ns);
95 0 : get_uts_ns(old_ns);
96 :
97 0 : if (!(flags & CLONE_NEWUTS))
98 : return old_ns;
99 :
100 0 : new_ns = clone_uts_ns(user_ns, old_ns);
101 :
102 0 : put_uts_ns(old_ns);
103 0 : return new_ns;
104 : }
105 :
106 0 : void free_uts_ns(struct uts_namespace *ns)
107 : {
108 0 : dec_uts_namespaces(ns->ucounts);
109 0 : put_user_ns(ns->user_ns);
110 0 : ns_free_inum(&ns->ns);
111 0 : kmem_cache_free(uts_ns_cache, ns);
112 0 : }
113 :
114 : static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
115 : {
116 0 : return container_of(ns, struct uts_namespace, ns);
117 : }
118 :
119 0 : static struct ns_common *utsns_get(struct task_struct *task)
120 : {
121 0 : struct uts_namespace *ns = NULL;
122 : struct nsproxy *nsproxy;
123 :
124 0 : task_lock(task);
125 0 : nsproxy = task->nsproxy;
126 0 : if (nsproxy) {
127 0 : ns = nsproxy->uts_ns;
128 : get_uts_ns(ns);
129 : }
130 0 : task_unlock(task);
131 :
132 0 : return ns ? &ns->ns : NULL;
133 : }
134 :
135 0 : static void utsns_put(struct ns_common *ns)
136 : {
137 0 : put_uts_ns(to_uts_ns(ns));
138 0 : }
139 :
140 0 : static int utsns_install(struct nsset *nsset, struct ns_common *new)
141 : {
142 0 : struct nsproxy *nsproxy = nsset->nsproxy;
143 0 : struct uts_namespace *ns = to_uts_ns(new);
144 :
145 0 : if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
146 0 : !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
147 : return -EPERM;
148 :
149 0 : get_uts_ns(ns);
150 0 : put_uts_ns(nsproxy->uts_ns);
151 0 : nsproxy->uts_ns = ns;
152 0 : return 0;
153 : }
154 :
155 0 : static struct user_namespace *utsns_owner(struct ns_common *ns)
156 : {
157 0 : return to_uts_ns(ns)->user_ns;
158 : }
159 :
160 : const struct proc_ns_operations utsns_operations = {
161 : .name = "uts",
162 : .type = CLONE_NEWUTS,
163 : .get = utsns_get,
164 : .put = utsns_put,
165 : .install = utsns_install,
166 : .owner = utsns_owner,
167 : };
168 :
169 1 : void __init uts_ns_init(void)
170 : {
171 1 : uts_ns_cache = kmem_cache_create_usercopy(
172 : "uts_namespace", sizeof(struct uts_namespace), 0,
173 : SLAB_PANIC|SLAB_ACCOUNT,
174 : offsetof(struct uts_namespace, name),
175 : sizeof_field(struct uts_namespace, name),
176 : NULL);
177 1 : }
|