Blame view

kernel/utsname.c 3.56 KB
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
1
2
3
4
5
6
7
8
9
10
  /*
   *  Copyright (C) 2004 IBM Corporation
   *
   *  Author: Serge Hallyn <serue@us.ibm.com>
   *
   *  This program is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU General Public License as
   *  published by the Free Software Foundation, version 2 of the
   *  License.
   */
9984de1a5   Paul Gortmaker   kernel: Map most ...
11
  #include <linux/export.h>
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
12
13
  #include <linux/uts.h>
  #include <linux/utsname.h>
467e9f4b5   Cedric Le Goater   fix create_new_na...
14
  #include <linux/err.h>
1aeb272cf   Robert P. J. Day   kernel: explicitl...
15
  #include <linux/slab.h>
59607db36   Serge E. Hallyn   userns: add a use...
16
  #include <linux/user_namespace.h>
0bb80f240   David Howells   proc: Split the n...
17
  #include <linux/proc_ns.h>
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
18

f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
19
20
21
22
23
24
25
26
27
  static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
  {
  	return inc_ucount(ns, current_euid(), UCOUNT_UTS_NAMESPACES);
  }
  
  static void dec_uts_namespaces(struct ucounts *ucounts)
  {
  	dec_ucount(ucounts, UCOUNT_UTS_NAMESPACES);
  }
4c2a7e72d   Alexey Dobriyan   utsns: extract cr...
28
29
30
31
32
33
34
35
36
  static struct uts_namespace *create_uts_ns(void)
  {
  	struct uts_namespace *uts_ns;
  
  	uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
  	if (uts_ns)
  		kref_init(&uts_ns->kref);
  	return uts_ns;
  }
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
37
  /*
071df104f   Serge E. Hallyn   [PATCH] namespace...
38
39
   * Clone a new ns copying an original utsname, setting refcount to 1
   * @old_ns: namespace to clone
bf5315366   Yuanhan Liu   kernel/utsname.c:...
40
   * Return ERR_PTR(-ENOMEM) on error (failure to kmalloc), new ns otherwise
071df104f   Serge E. Hallyn   [PATCH] namespace...
41
   */
bcf58e725   Eric W. Biederman   userns: Make crea...
42
  static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
bb96a6f50   Serge E. Hallyn   userns: allow set...
43
  					  struct uts_namespace *old_ns)
071df104f   Serge E. Hallyn   [PATCH] namespace...
44
45
  {
  	struct uts_namespace *ns;
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
46
  	struct ucounts *ucounts;
98f842e67   Eric W. Biederman   proc: Usable inod...
47
  	int err;
071df104f   Serge E. Hallyn   [PATCH] namespace...
48

df75e7748   Eric W. Biederman   userns: When the ...
49
  	err = -ENOSPC;
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
50
51
52
53
54
  	ucounts = inc_uts_namespaces(user_ns);
  	if (!ucounts)
  		goto fail;
  
  	err = -ENOMEM;
4c2a7e72d   Alexey Dobriyan   utsns: extract cr...
55
  	ns = create_uts_ns();
467e9f4b5   Cedric Le Goater   fix create_new_na...
56
  	if (!ns)
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
57
  		goto fail_dec;
467e9f4b5   Cedric Le Goater   fix create_new_na...
58

6344c433a   Al Viro   new helpers: ns_a...
59
  	err = ns_alloc_inum(&ns->ns);
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
60
61
  	if (err)
  		goto fail_free;
98f842e67   Eric W. Biederman   proc: Usable inod...
62

f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
63
  	ns->ucounts = ucounts;
33c429405   Al Viro   copy address of p...
64
  	ns->ns.ops = &utsns_operations;
efc63c4fb   Alexey Dobriyan   Fix UTS corruptio...
65
  	down_read(&uts_sem);
467e9f4b5   Cedric Le Goater   fix create_new_na...
66
  	memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
bcf58e725   Eric W. Biederman   userns: Make crea...
67
  	ns->user_ns = get_user_ns(user_ns);
efc63c4fb   Alexey Dobriyan   Fix UTS corruptio...
68
  	up_read(&uts_sem);
071df104f   Serge E. Hallyn   [PATCH] namespace...
69
  	return ns;
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
70
71
72
73
74
75
76
  
  fail_free:
  	kfree(ns);
  fail_dec:
  	dec_uts_namespaces(ucounts);
  fail:
  	return ERR_PTR(err);
071df104f   Serge E. Hallyn   [PATCH] namespace...
77
78
79
  }
  
  /*
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
80
81
82
83
84
   * Copy task tsk's utsname namespace, or clone it if flags
   * specifies CLONE_NEWUTS.  In latter case, changes to the
   * utsname of this process won't be seen by parent, and vice
   * versa.
   */
bb96a6f50   Serge E. Hallyn   userns: allow set...
85
  struct uts_namespace *copy_utsname(unsigned long flags,
bcf58e725   Eric W. Biederman   userns: Make crea...
86
  	struct user_namespace *user_ns, struct uts_namespace *old_ns)
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
87
  {
071df104f   Serge E. Hallyn   [PATCH] namespace...
88
  	struct uts_namespace *new_ns;
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
89

e3222c4ec   Badari Pulavarty   Merge sys_clone()...
90
  	BUG_ON(!old_ns);
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
91
  	get_uts_ns(old_ns);
071df104f   Serge E. Hallyn   [PATCH] namespace...
92
  	if (!(flags & CLONE_NEWUTS))
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
93
  		return old_ns;
071df104f   Serge E. Hallyn   [PATCH] namespace...
94

bcf58e725   Eric W. Biederman   userns: Make crea...
95
  	new_ns = clone_uts_ns(user_ns, old_ns);
071df104f   Serge E. Hallyn   [PATCH] namespace...
96

071df104f   Serge E. Hallyn   [PATCH] namespace...
97
  	put_uts_ns(old_ns);
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
98
  	return new_ns;
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
99
100
101
102
103
104
105
  }
  
  void free_uts_ns(struct kref *kref)
  {
  	struct uts_namespace *ns;
  
  	ns = container_of(kref, struct uts_namespace, kref);
f7af3d1c0   Eric W. Biederman   utsns: Add a limi...
106
  	dec_uts_namespaces(ns->ucounts);
59607db36   Serge E. Hallyn   userns: add a use...
107
  	put_user_ns(ns->user_ns);
6344c433a   Al Viro   new helpers: ns_a...
108
  	ns_free_inum(&ns->ns);
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
109
110
  	kfree(ns);
  }
34482e89a   Eric W. Biederman   ns proc: Add supp...
111

3c0411846   Al Viro   switch the rest o...
112
113
114
115
  static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
  {
  	return container_of(ns, struct uts_namespace, ns);
  }
64964528b   Al Viro   make proc_ns_oper...
116
  static struct ns_common *utsns_get(struct task_struct *task)
34482e89a   Eric W. Biederman   ns proc: Add supp...
117
118
119
  {
  	struct uts_namespace *ns = NULL;
  	struct nsproxy *nsproxy;
728dba3a3   Eric W. Biederman   namespaces: Use t...
120
121
  	task_lock(task);
  	nsproxy = task->nsproxy;
34482e89a   Eric W. Biederman   ns proc: Add supp...
122
123
124
125
  	if (nsproxy) {
  		ns = nsproxy->uts_ns;
  		get_uts_ns(ns);
  	}
728dba3a3   Eric W. Biederman   namespaces: Use t...
126
  	task_unlock(task);
34482e89a   Eric W. Biederman   ns proc: Add supp...
127

3c0411846   Al Viro   switch the rest o...
128
  	return ns ? &ns->ns : NULL;
34482e89a   Eric W. Biederman   ns proc: Add supp...
129
  }
64964528b   Al Viro   make proc_ns_oper...
130
  static void utsns_put(struct ns_common *ns)
34482e89a   Eric W. Biederman   ns proc: Add supp...
131
  {
3c0411846   Al Viro   switch the rest o...
132
  	put_uts_ns(to_uts_ns(ns));
34482e89a   Eric W. Biederman   ns proc: Add supp...
133
  }
64964528b   Al Viro   make proc_ns_oper...
134
  static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
34482e89a   Eric W. Biederman   ns proc: Add supp...
135
  {
3c0411846   Al Viro   switch the rest o...
136
  	struct uts_namespace *ns = to_uts_ns(new);
142e1d1d5   Eric W. Biederman   userns: Allow unp...
137

5e4a08476   Eric W. Biederman   userns: Require C...
138
  	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
c7b96acf1   Eric W. Biederman   userns: Kill nso...
139
  	    !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
142e1d1d5   Eric W. Biederman   userns: Allow unp...
140
  		return -EPERM;
34482e89a   Eric W. Biederman   ns proc: Add supp...
141
142
143
144
145
  	get_uts_ns(ns);
  	put_uts_ns(nsproxy->uts_ns);
  	nsproxy->uts_ns = ns;
  	return 0;
  }
bcac25a58   Andrey Vagin   kernel: add a hel...
146
147
148
149
  static struct user_namespace *utsns_owner(struct ns_common *ns)
  {
  	return to_uts_ns(ns)->user_ns;
  }
34482e89a   Eric W. Biederman   ns proc: Add supp...
150
151
152
153
154
155
  const struct proc_ns_operations utsns_operations = {
  	.name		= "uts",
  	.type		= CLONE_NEWUTS,
  	.get		= utsns_get,
  	.put		= utsns_put,
  	.install	= utsns_install,
bcac25a58   Andrey Vagin   kernel: add a hel...
156
  	.owner		= utsns_owner,
34482e89a   Eric W. Biederman   ns proc: Add supp...
157
  };