aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/utsname.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/utsname.c')
-rw-r--r--kernel/utsname.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 831ea7108232..6976cd47dcf6 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -17,6 +17,16 @@
17#include <linux/user_namespace.h> 17#include <linux/user_namespace.h>
18#include <linux/proc_ns.h> 18#include <linux/proc_ns.h>
19 19
20static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
21{
22 return inc_ucount(ns, current_euid(), UCOUNT_UTS_NAMESPACES);
23}
24
25static void dec_uts_namespaces(struct ucounts *ucounts)
26{
27 dec_ucount(ucounts, UCOUNT_UTS_NAMESPACES);
28}
29
20static struct uts_namespace *create_uts_ns(void) 30static struct uts_namespace *create_uts_ns(void)
21{ 31{
22 struct uts_namespace *uts_ns; 32 struct uts_namespace *uts_ns;
@@ -36,18 +46,24 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
36 struct uts_namespace *old_ns) 46 struct uts_namespace *old_ns)
37{ 47{
38 struct uts_namespace *ns; 48 struct uts_namespace *ns;
49 struct ucounts *ucounts;
39 int err; 50 int err;
40 51
52 err = -ENOSPC;
53 ucounts = inc_uts_namespaces(user_ns);
54 if (!ucounts)
55 goto fail;
56
57 err = -ENOMEM;
41 ns = create_uts_ns(); 58 ns = create_uts_ns();
42 if (!ns) 59 if (!ns)
43 return ERR_PTR(-ENOMEM); 60 goto fail_dec;
44 61
45 err = ns_alloc_inum(&ns->ns); 62 err = ns_alloc_inum(&ns->ns);
46 if (err) { 63 if (err)
47 kfree(ns); 64 goto fail_free;
48 return ERR_PTR(err);
49 }
50 65
66 ns->ucounts = ucounts;
51 ns->ns.ops = &utsns_operations; 67 ns->ns.ops = &utsns_operations;
52 68
53 down_read(&uts_sem); 69 down_read(&uts_sem);
@@ -55,6 +71,13 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
55 ns->user_ns = get_user_ns(user_ns); 71 ns->user_ns = get_user_ns(user_ns);
56 up_read(&uts_sem); 72 up_read(&uts_sem);
57 return ns; 73 return ns;
74
75fail_free:
76 kfree(ns);
77fail_dec:
78 dec_uts_namespaces(ucounts);
79fail:
80 return ERR_PTR(err);
58} 81}
59 82
60/* 83/*
@@ -85,6 +108,7 @@ void free_uts_ns(struct kref *kref)
85 struct uts_namespace *ns; 108 struct uts_namespace *ns;
86 109
87 ns = container_of(kref, struct uts_namespace, kref); 110 ns = container_of(kref, struct uts_namespace, kref);
111 dec_uts_namespaces(ns->ucounts);
88 put_user_ns(ns->user_ns); 112 put_user_ns(ns->user_ns);
89 ns_free_inum(&ns->ns); 113 ns_free_inum(&ns->ns);
90 kfree(ns); 114 kfree(ns);
@@ -130,10 +154,16 @@ static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
130 return 0; 154 return 0;
131} 155}
132 156
157static struct user_namespace *utsns_owner(struct ns_common *ns)
158{
159 return to_uts_ns(ns)->user_ns;
160}
161
133const struct proc_ns_operations utsns_operations = { 162const struct proc_ns_operations utsns_operations = {
134 .name = "uts", 163 .name = "uts",
135 .type = CLONE_NEWUTS, 164 .type = CLONE_NEWUTS,
136 .get = utsns_get, 165 .get = utsns_get,
137 .put = utsns_put, 166 .put = utsns_put,
138 .install = utsns_install, 167 .install = utsns_install,
168 .owner = utsns_owner,
139}; 169};