Blame view

kernel/utsname.c 2.96 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

4c2a7e72d   Alexey Dobriyan   utsns: extract cr...
19
20
21
22
23
24
25
26
27
  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...
28
  /*
071df104f   Serge E. Hallyn   [PATCH] namespace...
29
30
   * Clone a new ns copying an original utsname, setting refcount to 1
   * @old_ns: namespace to clone
bf5315366   Yuanhan Liu   kernel/utsname.c:...
31
   * Return ERR_PTR(-ENOMEM) on error (failure to kmalloc), new ns otherwise
071df104f   Serge E. Hallyn   [PATCH] namespace...
32
   */
bcf58e725   Eric W. Biederman   userns: Make crea...
33
  static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
bb96a6f50   Serge E. Hallyn   userns: allow set...
34
  					  struct uts_namespace *old_ns)
071df104f   Serge E. Hallyn   [PATCH] namespace...
35
36
  {
  	struct uts_namespace *ns;
98f842e67   Eric W. Biederman   proc: Usable inod...
37
  	int err;
071df104f   Serge E. Hallyn   [PATCH] namespace...
38

4c2a7e72d   Alexey Dobriyan   utsns: extract cr...
39
  	ns = create_uts_ns();
467e9f4b5   Cedric Le Goater   fix create_new_na...
40
41
  	if (!ns)
  		return ERR_PTR(-ENOMEM);
6344c433a   Al Viro   new helpers: ns_a...
42
  	err = ns_alloc_inum(&ns->ns);
98f842e67   Eric W. Biederman   proc: Usable inod...
43
44
45
46
  	if (err) {
  		kfree(ns);
  		return ERR_PTR(err);
  	}
33c429405   Al Viro   copy address of p...
47
  	ns->ns.ops = &utsns_operations;
efc63c4fb   Alexey Dobriyan   Fix UTS corruptio...
48
  	down_read(&uts_sem);
467e9f4b5   Cedric Le Goater   fix create_new_na...
49
  	memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
bcf58e725   Eric W. Biederman   userns: Make crea...
50
  	ns->user_ns = get_user_ns(user_ns);
efc63c4fb   Alexey Dobriyan   Fix UTS corruptio...
51
  	up_read(&uts_sem);
071df104f   Serge E. Hallyn   [PATCH] namespace...
52
53
54
55
  	return ns;
  }
  
  /*
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
56
57
58
59
60
   * 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...
61
  struct uts_namespace *copy_utsname(unsigned long flags,
bcf58e725   Eric W. Biederman   userns: Make crea...
62
  	struct user_namespace *user_ns, struct uts_namespace *old_ns)
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
63
  {
071df104f   Serge E. Hallyn   [PATCH] namespace...
64
  	struct uts_namespace *new_ns;
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
65

e3222c4ec   Badari Pulavarty   Merge sys_clone()...
66
  	BUG_ON(!old_ns);
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
67
  	get_uts_ns(old_ns);
071df104f   Serge E. Hallyn   [PATCH] namespace...
68
  	if (!(flags & CLONE_NEWUTS))
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
69
  		return old_ns;
071df104f   Serge E. Hallyn   [PATCH] namespace...
70

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

071df104f   Serge E. Hallyn   [PATCH] namespace...
73
  	put_uts_ns(old_ns);
e3222c4ec   Badari Pulavarty   Merge sys_clone()...
74
  	return new_ns;
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
75
76
77
78
79
80
81
  }
  
  void free_uts_ns(struct kref *kref)
  {
  	struct uts_namespace *ns;
  
  	ns = container_of(kref, struct uts_namespace, kref);
59607db36   Serge E. Hallyn   userns: add a use...
82
  	put_user_ns(ns->user_ns);
6344c433a   Al Viro   new helpers: ns_a...
83
  	ns_free_inum(&ns->ns);
4865ecf13   Serge E. Hallyn   [PATCH] namespace...
84
85
  	kfree(ns);
  }
34482e89a   Eric W. Biederman   ns proc: Add supp...
86

3c0411846   Al Viro   switch the rest o...
87
88
89
90
  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...
91
  static struct ns_common *utsns_get(struct task_struct *task)
34482e89a   Eric W. Biederman   ns proc: Add supp...
92
93
94
  {
  	struct uts_namespace *ns = NULL;
  	struct nsproxy *nsproxy;
728dba3a3   Eric W. Biederman   namespaces: Use t...
95
96
  	task_lock(task);
  	nsproxy = task->nsproxy;
34482e89a   Eric W. Biederman   ns proc: Add supp...
97
98
99
100
  	if (nsproxy) {
  		ns = nsproxy->uts_ns;
  		get_uts_ns(ns);
  	}
728dba3a3   Eric W. Biederman   namespaces: Use t...
101
  	task_unlock(task);
34482e89a   Eric W. Biederman   ns proc: Add supp...
102

3c0411846   Al Viro   switch the rest o...
103
  	return ns ? &ns->ns : NULL;
34482e89a   Eric W. Biederman   ns proc: Add supp...
104
  }
64964528b   Al Viro   make proc_ns_oper...
105
  static void utsns_put(struct ns_common *ns)
34482e89a   Eric W. Biederman   ns proc: Add supp...
106
  {
3c0411846   Al Viro   switch the rest o...
107
  	put_uts_ns(to_uts_ns(ns));
34482e89a   Eric W. Biederman   ns proc: Add supp...
108
  }
64964528b   Al Viro   make proc_ns_oper...
109
  static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
34482e89a   Eric W. Biederman   ns proc: Add supp...
110
  {
3c0411846   Al Viro   switch the rest o...
111
  	struct uts_namespace *ns = to_uts_ns(new);
142e1d1d5   Eric W. Biederman   userns: Allow unp...
112

5e4a08476   Eric W. Biederman   userns: Require C...
113
  	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
c7b96acf1   Eric W. Biederman   userns: Kill nso...
114
  	    !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
142e1d1d5   Eric W. Biederman   userns: Allow unp...
115
  		return -EPERM;
34482e89a   Eric W. Biederman   ns proc: Add supp...
116
117
118
119
120
121
122
123
124
125
126
127
128
  	get_uts_ns(ns);
  	put_uts_ns(nsproxy->uts_ns);
  	nsproxy->uts_ns = ns;
  	return 0;
  }
  
  const struct proc_ns_operations utsns_operations = {
  	.name		= "uts",
  	.type		= CLONE_NEWUTS,
  	.get		= utsns_get,
  	.put		= utsns_put,
  	.install	= utsns_install,
  };