aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/utsname.c
diff options
context:
space:
mode:
authorSerge E. Hallyn <serue@us.ibm.com>2006-10-02 05:18:17 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:22 -0400
commit071df104f808b8195c40643dcb4d060681742e29 (patch)
treee5c3355e526e0182797d59c7e80062fbc2bb7d77 /kernel/utsname.c
parentbf47fdcda65b44dbd674eeedcaa06e0aa28a5a00 (diff)
[PATCH] namespaces: utsname: implement CLONE_NEWUTS flag
Implement a CLONE_NEWUTS flag, and use it at clone and sys_unshare. [clg@fr.ibm.com: IPC unshare fix] [bunk@stusta.de: cleanup] Signed-off-by: Serge Hallyn <serue@us.ibm.com> Cc: Kirill Korotaev <dev@openvz.org> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Herbert Poetzl <herbert@13thfloor.at> Cc: Andrey Savochkin <saw@sw.ru> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Cedric Le Goater <clg@fr.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/utsname.c')
-rw-r--r--kernel/utsname.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 1824384ecfa3..c859164a6993 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -15,6 +15,41 @@
15#include <linux/version.h> 15#include <linux/version.h>
16 16
17/* 17/*
18 * Clone a new ns copying an original utsname, setting refcount to 1
19 * @old_ns: namespace to clone
20 * Return NULL on error (failure to kmalloc), new ns otherwise
21 */
22static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)
23{
24 struct uts_namespace *ns;
25
26 ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
27 if (ns) {
28 memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
29 kref_init(&ns->kref);
30 }
31 return ns;
32}
33
34/*
35 * unshare the current process' utsname namespace.
36 * called only in sys_unshare()
37 */
38int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
39{
40 if (unshare_flags & CLONE_NEWUTS) {
41 if (!capable(CAP_SYS_ADMIN))
42 return -EPERM;
43
44 *new_uts = clone_uts_ns(current->nsproxy->uts_ns);
45 if (!*new_uts)
46 return -ENOMEM;
47 }
48
49 return 0;
50}
51
52/*
18 * Copy task tsk's utsname namespace, or clone it if flags 53 * Copy task tsk's utsname namespace, or clone it if flags
19 * specifies CLONE_NEWUTS. In latter case, changes to the 54 * specifies CLONE_NEWUTS. In latter case, changes to the
20 * utsname of this process won't be seen by parent, and vice 55 * utsname of this process won't be seen by parent, and vice
@@ -23,6 +58,7 @@
23int copy_utsname(int flags, struct task_struct *tsk) 58int copy_utsname(int flags, struct task_struct *tsk)
24{ 59{
25 struct uts_namespace *old_ns = tsk->nsproxy->uts_ns; 60 struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
61 struct uts_namespace *new_ns;
26 int err = 0; 62 int err = 0;
27 63
28 if (!old_ns) 64 if (!old_ns)
@@ -30,6 +66,23 @@ int copy_utsname(int flags, struct task_struct *tsk)
30 66
31 get_uts_ns(old_ns); 67 get_uts_ns(old_ns);
32 68
69 if (!(flags & CLONE_NEWUTS))
70 return 0;
71
72 if (!capable(CAP_SYS_ADMIN)) {
73 err = -EPERM;
74 goto out;
75 }
76
77 new_ns = clone_uts_ns(old_ns);
78 if (!new_ns) {
79 err = -ENOMEM;
80 goto out;
81 }
82 tsk->nsproxy->uts_ns = new_ns;
83
84out:
85 put_uts_ns(old_ns);
33 return err; 86 return err;
34} 87}
35 88