X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=kernel%2Futsname.c;h=8a82b4b8ea52cb3690e25bf039eaf32ff5c8c079;hb=595aac488b546c7185be7e29c8ae165a588b2a9f;hp=c859164a699311a10021f37f06c369e34ac4f4d5;hpb=071df104f808b8195c40643dcb4d060681742e29;p=safe%2Fjmp%2Flinux-2.6 diff --git a/kernel/utsname.c b/kernel/utsname.c index c859164..8a82b4b 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -12,7 +12,18 @@ #include #include #include -#include +#include +#include + +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; +} /* * Clone a new ns copying an original utsname, setting refcount to 1 @@ -23,30 +34,14 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns) { struct uts_namespace *ns; - ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL); - if (ns) { - memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); - kref_init(&ns->kref); - } - return ns; -} - -/* - * unshare the current process' utsname namespace. - * called only in sys_unshare() - */ -int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts) -{ - if (unshare_flags & CLONE_NEWUTS) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - *new_uts = clone_uts_ns(current->nsproxy->uts_ns); - if (!*new_uts) - return -ENOMEM; - } + ns = create_uts_ns(); + if (!ns) + return ERR_PTR(-ENOMEM); - return 0; + down_read(&uts_sem); + memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); + up_read(&uts_sem); + return ns; } /* @@ -55,35 +50,20 @@ int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts) * utsname of this process won't be seen by parent, and vice * versa. */ -int copy_utsname(int flags, struct task_struct *tsk) +struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *old_ns) { - struct uts_namespace *old_ns = tsk->nsproxy->uts_ns; struct uts_namespace *new_ns; - int err = 0; - - if (!old_ns) - return 0; + BUG_ON(!old_ns); get_uts_ns(old_ns); if (!(flags & CLONE_NEWUTS)) - return 0; - - if (!capable(CAP_SYS_ADMIN)) { - err = -EPERM; - goto out; - } + return old_ns; new_ns = clone_uts_ns(old_ns); - if (!new_ns) { - err = -ENOMEM; - goto out; - } - tsk->nsproxy->uts_ns = new_ns; -out: put_uts_ns(old_ns); - return err; + return new_ns; } void free_uts_ns(struct kref *kref)