1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2ab516013SSerge E. Hallyn /* 3ab516013SSerge E. Hallyn * Copyright (C) 2006 IBM Corporation 4ab516013SSerge E. Hallyn * 5ab516013SSerge E. Hallyn * Author: Serge Hallyn <serue@us.ibm.com> 6ab516013SSerge E. Hallyn * 725b21cb2SKirill Korotaev * Jun 2006 - namespaces support 825b21cb2SKirill Korotaev * OpenVZ, SWsoft Inc. 925b21cb2SKirill Korotaev * Pavel Emelianov <xemul@openvz.org> 10ab516013SSerge E. Hallyn */ 11ab516013SSerge E. Hallyn 125a0e3ad6STejun Heo #include <linux/slab.h> 139984de1aSPaul Gortmaker #include <linux/export.h> 14ab516013SSerge E. Hallyn #include <linux/nsproxy.h> 150437eb59SSerge E. Hallyn #include <linux/init_task.h> 166b3286edSKirill Korotaev #include <linux/mnt_namespace.h> 174865ecf1SSerge E. Hallyn #include <linux/utsname.h> 189a575a92SCedric Le Goater #include <linux/pid_namespace.h> 199dd776b6SEric W. Biederman #include <net/net_namespace.h> 20ae5e1b22SPavel Emelyanov #include <linux/ipc_namespace.h> 21769071acSAndrei Vagin #include <linux/time_namespace.h> 22f2a8d52eSChristian Brauner #include <linux/fs_struct.h> 230bb80f24SDavid Howells #include <linux/proc_ns.h> 240663c6f8SEric W. Biederman #include <linux/file.h> 250663c6f8SEric W. Biederman #include <linux/syscalls.h> 26a79a908fSAditya Kali #include <linux/cgroup.h> 27e4222673SHari Bathini #include <linux/perf_event.h> 280437eb59SSerge E. Hallyn 2998c0d07cSCedric Le Goater static struct kmem_cache *nsproxy_cachep; 3098c0d07cSCedric Le Goater 318467005dSAlexey Dobriyan struct nsproxy init_nsproxy = { 328467005dSAlexey Dobriyan .count = ATOMIC_INIT(1), 338467005dSAlexey Dobriyan .uts_ns = &init_uts_ns, 348467005dSAlexey Dobriyan #if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC) 358467005dSAlexey Dobriyan .ipc_ns = &init_ipc_ns, 368467005dSAlexey Dobriyan #endif 378467005dSAlexey Dobriyan .mnt_ns = NULL, 38c2b1df2eSAndy Lutomirski .pid_ns_for_children = &init_pid_ns, 398467005dSAlexey Dobriyan #ifdef CONFIG_NET 408467005dSAlexey Dobriyan .net_ns = &init_net, 418467005dSAlexey Dobriyan #endif 42a79a908fSAditya Kali #ifdef CONFIG_CGROUPS 43a79a908fSAditya Kali .cgroup_ns = &init_cgroup_ns, 44a79a908fSAditya Kali #endif 45769071acSAndrei Vagin #ifdef CONFIG_TIME_NS 46769071acSAndrei Vagin .time_ns = &init_time_ns, 47769071acSAndrei Vagin .time_ns_for_children = &init_time_ns, 48769071acSAndrei Vagin #endif 498467005dSAlexey Dobriyan }; 50ab516013SSerge E. Hallyn 5190af90d7SAlexey Dobriyan static inline struct nsproxy *create_nsproxy(void) 52ab516013SSerge E. Hallyn { 5390af90d7SAlexey Dobriyan struct nsproxy *nsproxy; 54ab516013SSerge E. Hallyn 5590af90d7SAlexey Dobriyan nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL); 5690af90d7SAlexey Dobriyan if (nsproxy) 5790af90d7SAlexey Dobriyan atomic_set(&nsproxy->count, 1); 5890af90d7SAlexey Dobriyan return nsproxy; 59ab516013SSerge E. Hallyn } 60ab516013SSerge E. Hallyn 61ab516013SSerge E. Hallyn /* 62e3222c4eSBadari Pulavarty * Create new nsproxy and all of its the associated namespaces. 63e3222c4eSBadari Pulavarty * Return the newly created nsproxy. Do not attach this to the task, 64e3222c4eSBadari Pulavarty * leave it to the caller to do proper locking and attach it to task. 65ab516013SSerge E. Hallyn */ 66213dd266SEric W. Biederman static struct nsproxy *create_new_namespaces(unsigned long flags, 67bcf58e72SEric W. Biederman struct task_struct *tsk, struct user_namespace *user_ns, 68bcf58e72SEric W. Biederman struct fs_struct *new_fs) 69ab516013SSerge E. Hallyn { 70e3222c4eSBadari Pulavarty struct nsproxy *new_nsp; 71467e9f4bSCedric Le Goater int err; 72ab516013SSerge E. Hallyn 7390af90d7SAlexey Dobriyan new_nsp = create_nsproxy(); 74e3222c4eSBadari Pulavarty if (!new_nsp) 75e3222c4eSBadari Pulavarty return ERR_PTR(-ENOMEM); 761651e14eSSerge E. Hallyn 77bcf58e72SEric W. Biederman new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs); 78467e9f4bSCedric Le Goater if (IS_ERR(new_nsp->mnt_ns)) { 79467e9f4bSCedric Le Goater err = PTR_ERR(new_nsp->mnt_ns); 80e3222c4eSBadari Pulavarty goto out_ns; 81467e9f4bSCedric Le Goater } 82e3222c4eSBadari Pulavarty 83bcf58e72SEric W. Biederman new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns); 84467e9f4bSCedric Le Goater if (IS_ERR(new_nsp->uts_ns)) { 85467e9f4bSCedric Le Goater err = PTR_ERR(new_nsp->uts_ns); 86e3222c4eSBadari Pulavarty goto out_uts; 87467e9f4bSCedric Le Goater } 88e3222c4eSBadari Pulavarty 89bcf58e72SEric W. Biederman new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns); 90467e9f4bSCedric Le Goater if (IS_ERR(new_nsp->ipc_ns)) { 91467e9f4bSCedric Le Goater err = PTR_ERR(new_nsp->ipc_ns); 92e3222c4eSBadari Pulavarty goto out_ipc; 93467e9f4bSCedric Le Goater } 94e3222c4eSBadari Pulavarty 95c2b1df2eSAndy Lutomirski new_nsp->pid_ns_for_children = 96c2b1df2eSAndy Lutomirski copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children); 97c2b1df2eSAndy Lutomirski if (IS_ERR(new_nsp->pid_ns_for_children)) { 98c2b1df2eSAndy Lutomirski err = PTR_ERR(new_nsp->pid_ns_for_children); 99e3222c4eSBadari Pulavarty goto out_pid; 100467e9f4bSCedric Le Goater } 101e3222c4eSBadari Pulavarty 102a79a908fSAditya Kali new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns, 103a79a908fSAditya Kali tsk->nsproxy->cgroup_ns); 104a79a908fSAditya Kali if (IS_ERR(new_nsp->cgroup_ns)) { 105a79a908fSAditya Kali err = PTR_ERR(new_nsp->cgroup_ns); 106a79a908fSAditya Kali goto out_cgroup; 107a79a908fSAditya Kali } 108a79a908fSAditya Kali 109bcf58e72SEric W. Biederman new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns); 1109dd776b6SEric W. Biederman if (IS_ERR(new_nsp->net_ns)) { 1119dd776b6SEric W. Biederman err = PTR_ERR(new_nsp->net_ns); 1129dd776b6SEric W. Biederman goto out_net; 1139dd776b6SEric W. Biederman } 1149dd776b6SEric W. Biederman 115769071acSAndrei Vagin new_nsp->time_ns_for_children = copy_time_ns(flags, user_ns, 116769071acSAndrei Vagin tsk->nsproxy->time_ns_for_children); 117769071acSAndrei Vagin if (IS_ERR(new_nsp->time_ns_for_children)) { 118769071acSAndrei Vagin err = PTR_ERR(new_nsp->time_ns_for_children); 119769071acSAndrei Vagin goto out_time; 120769071acSAndrei Vagin } 121769071acSAndrei Vagin new_nsp->time_ns = get_time_ns(tsk->nsproxy->time_ns); 122769071acSAndrei Vagin 123e3222c4eSBadari Pulavarty return new_nsp; 124e3222c4eSBadari Pulavarty 125769071acSAndrei Vagin out_time: 126769071acSAndrei Vagin put_net(new_nsp->net_ns); 1279dd776b6SEric W. Biederman out_net: 128a79a908fSAditya Kali put_cgroup_ns(new_nsp->cgroup_ns); 129a79a908fSAditya Kali out_cgroup: 130c2b1df2eSAndy Lutomirski if (new_nsp->pid_ns_for_children) 131c2b1df2eSAndy Lutomirski put_pid_ns(new_nsp->pid_ns_for_children); 132e3222c4eSBadari Pulavarty out_pid: 133e3222c4eSBadari Pulavarty if (new_nsp->ipc_ns) 134e3222c4eSBadari Pulavarty put_ipc_ns(new_nsp->ipc_ns); 135e3222c4eSBadari Pulavarty out_ipc: 136e3222c4eSBadari Pulavarty if (new_nsp->uts_ns) 137e3222c4eSBadari Pulavarty put_uts_ns(new_nsp->uts_ns); 138e3222c4eSBadari Pulavarty out_uts: 139e3222c4eSBadari Pulavarty if (new_nsp->mnt_ns) 140e3222c4eSBadari Pulavarty put_mnt_ns(new_nsp->mnt_ns); 141e3222c4eSBadari Pulavarty out_ns: 14298c0d07cSCedric Le Goater kmem_cache_free(nsproxy_cachep, new_nsp); 143467e9f4bSCedric Le Goater return ERR_PTR(err); 144ab516013SSerge E. Hallyn } 145ab516013SSerge E. Hallyn 146ab516013SSerge E. Hallyn /* 147ab516013SSerge E. Hallyn * called from clone. This now handles copy for nsproxy and all 148ab516013SSerge E. Hallyn * namespaces therein. 149ab516013SSerge E. Hallyn */ 150213dd266SEric W. Biederman int copy_namespaces(unsigned long flags, struct task_struct *tsk) 151ab516013SSerge E. Hallyn { 152ab516013SSerge E. Hallyn struct nsproxy *old_ns = tsk->nsproxy; 153b33c77efSEric W. Biederman struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); 1541651e14eSSerge E. Hallyn struct nsproxy *new_ns; 155769071acSAndrei Vagin int ret; 156ab516013SSerge E. Hallyn 157dbef0c1cSEric W. Biederman if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 158a79a908fSAditya Kali CLONE_NEWPID | CLONE_NEWNET | 159769071acSAndrei Vagin CLONE_NEWCGROUP | CLONE_NEWTIME)))) { 160769071acSAndrei Vagin if (likely(old_ns->time_ns_for_children == old_ns->time_ns)) { 161ab516013SSerge E. Hallyn get_nsproxy(old_ns); 162ab516013SSerge E. Hallyn return 0; 163e3222c4eSBadari Pulavarty } 164769071acSAndrei Vagin } else if (!ns_capable(user_ns, CAP_SYS_ADMIN)) 165dbef0c1cSEric W. Biederman return -EPERM; 166dbef0c1cSEric W. Biederman 16702fdb36aSSerge E. Hallyn /* 16802fdb36aSSerge E. Hallyn * CLONE_NEWIPC must detach from the undolist: after switching 16902fdb36aSSerge E. Hallyn * to a new ipc namespace, the semaphore arrays from the old 17002fdb36aSSerge E. Hallyn * namespace are unreachable. In clone parlance, CLONE_SYSVSEM 17102fdb36aSSerge E. Hallyn * means share undolist with parent, so we must forbid using 17202fdb36aSSerge E. Hallyn * it along with CLONE_NEWIPC. 17302fdb36aSSerge E. Hallyn */ 17421e85194SRaphael S.Carvalho if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == 175dbef0c1cSEric W. Biederman (CLONE_NEWIPC | CLONE_SYSVSEM)) 176dbef0c1cSEric W. Biederman return -EINVAL; 17702fdb36aSSerge E. Hallyn 178d7d48f62SYuanhan Liu new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); 179dbef0c1cSEric W. Biederman if (IS_ERR(new_ns)) 180dbef0c1cSEric W. Biederman return PTR_ERR(new_ns); 1811651e14eSSerge E. Hallyn 182769071acSAndrei Vagin ret = timens_on_fork(new_ns, tsk); 183769071acSAndrei Vagin if (ret) { 184769071acSAndrei Vagin free_nsproxy(new_ns); 185769071acSAndrei Vagin return ret; 186769071acSAndrei Vagin } 187769071acSAndrei Vagin 1881651e14eSSerge E. Hallyn tsk->nsproxy = new_ns; 189dbef0c1cSEric W. Biederman return 0; 190ab516013SSerge E. Hallyn } 191ab516013SSerge E. Hallyn 192ab516013SSerge E. Hallyn void free_nsproxy(struct nsproxy *ns) 193ab516013SSerge E. Hallyn { 1946b3286edSKirill Korotaev if (ns->mnt_ns) 1956b3286edSKirill Korotaev put_mnt_ns(ns->mnt_ns); 1964865ecf1SSerge E. Hallyn if (ns->uts_ns) 1974865ecf1SSerge E. Hallyn put_uts_ns(ns->uts_ns); 19825b21cb2SKirill Korotaev if (ns->ipc_ns) 19925b21cb2SKirill Korotaev put_ipc_ns(ns->ipc_ns); 200c2b1df2eSAndy Lutomirski if (ns->pid_ns_for_children) 201c2b1df2eSAndy Lutomirski put_pid_ns(ns->pid_ns_for_children); 202769071acSAndrei Vagin if (ns->time_ns) 203769071acSAndrei Vagin put_time_ns(ns->time_ns); 204769071acSAndrei Vagin if (ns->time_ns_for_children) 205769071acSAndrei Vagin put_time_ns(ns->time_ns_for_children); 206a79a908fSAditya Kali put_cgroup_ns(ns->cgroup_ns); 2079dd776b6SEric W. Biederman put_net(ns->net_ns); 20898c0d07cSCedric Le Goater kmem_cache_free(nsproxy_cachep, ns); 209ab516013SSerge E. Hallyn } 210e3222c4eSBadari Pulavarty 211e3222c4eSBadari Pulavarty /* 212e3222c4eSBadari Pulavarty * Called from unshare. Unshare all the namespaces part of nsproxy. 2134e71e474SCedric Le Goater * On success, returns the new nsproxy. 214e3222c4eSBadari Pulavarty */ 215e3222c4eSBadari Pulavarty int unshare_nsproxy_namespaces(unsigned long unshare_flags, 216b2e0d987SEric W. Biederman struct nsproxy **new_nsp, struct cred *new_cred, struct fs_struct *new_fs) 217e3222c4eSBadari Pulavarty { 218bcf58e72SEric W. Biederman struct user_namespace *user_ns; 219e3222c4eSBadari Pulavarty int err = 0; 220e3222c4eSBadari Pulavarty 22177ec739dSSerge E. Hallyn if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 222769071acSAndrei Vagin CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP | 223769071acSAndrei Vagin CLONE_NEWTIME))) 224e3222c4eSBadari Pulavarty return 0; 225e3222c4eSBadari Pulavarty 226b2e0d987SEric W. Biederman user_ns = new_cred ? new_cred->user_ns : current_user_ns(); 227b2e0d987SEric W. Biederman if (!ns_capable(user_ns, CAP_SYS_ADMIN)) 228e3222c4eSBadari Pulavarty return -EPERM; 229e3222c4eSBadari Pulavarty 230bcf58e72SEric W. Biederman *new_nsp = create_new_namespaces(unshare_flags, current, user_ns, 231e3222c4eSBadari Pulavarty new_fs ? new_fs : current->fs); 232858d72eaSSerge E. Hallyn if (IS_ERR(*new_nsp)) { 233e3222c4eSBadari Pulavarty err = PTR_ERR(*new_nsp); 234858d72eaSSerge E. Hallyn goto out; 235858d72eaSSerge E. Hallyn } 236858d72eaSSerge E. Hallyn 237858d72eaSSerge E. Hallyn out: 238e3222c4eSBadari Pulavarty return err; 239e3222c4eSBadari Pulavarty } 24098c0d07cSCedric Le Goater 241cf7b708cSPavel Emelyanov void switch_task_namespaces(struct task_struct *p, struct nsproxy *new) 242cf7b708cSPavel Emelyanov { 243cf7b708cSPavel Emelyanov struct nsproxy *ns; 244cf7b708cSPavel Emelyanov 245cf7b708cSPavel Emelyanov might_sleep(); 246cf7b708cSPavel Emelyanov 247728dba3aSEric W. Biederman task_lock(p); 248cf7b708cSPavel Emelyanov ns = p->nsproxy; 249728dba3aSEric W. Biederman p->nsproxy = new; 250728dba3aSEric W. Biederman task_unlock(p); 251cf7b708cSPavel Emelyanov 252728dba3aSEric W. Biederman if (ns && atomic_dec_and_test(&ns->count)) 253cf7b708cSPavel Emelyanov free_nsproxy(ns); 254cf7b708cSPavel Emelyanov } 255cf7b708cSPavel Emelyanov 256cf7b708cSPavel Emelyanov void exit_task_namespaces(struct task_struct *p) 257cf7b708cSPavel Emelyanov { 258cf7b708cSPavel Emelyanov switch_task_namespaces(p, NULL); 259cf7b708cSPavel Emelyanov } 260cf7b708cSPavel Emelyanov 261f2a8d52eSChristian Brauner static void put_nsset(struct nsset *nsset) 262f2a8d52eSChristian Brauner { 263f2a8d52eSChristian Brauner unsigned flags = nsset->flags; 264f2a8d52eSChristian Brauner 265f2a8d52eSChristian Brauner if (flags & CLONE_NEWUSER) 266f2a8d52eSChristian Brauner put_cred(nsset_cred(nsset)); 267f2a8d52eSChristian Brauner if (nsset->nsproxy) 268f2a8d52eSChristian Brauner free_nsproxy(nsset->nsproxy); 269f2a8d52eSChristian Brauner } 270f2a8d52eSChristian Brauner 271f2a8d52eSChristian Brauner static int prepare_nsset(int nstype, struct nsset *nsset) 272f2a8d52eSChristian Brauner { 273f2a8d52eSChristian Brauner struct task_struct *me = current; 274f2a8d52eSChristian Brauner 275f2a8d52eSChristian Brauner nsset->nsproxy = create_new_namespaces(0, me, current_user_ns(), me->fs); 276f2a8d52eSChristian Brauner if (IS_ERR(nsset->nsproxy)) 277f2a8d52eSChristian Brauner return PTR_ERR(nsset->nsproxy); 278f2a8d52eSChristian Brauner 279f2a8d52eSChristian Brauner if (nstype == CLONE_NEWUSER) 280f2a8d52eSChristian Brauner nsset->cred = prepare_creds(); 281f2a8d52eSChristian Brauner else 282f2a8d52eSChristian Brauner nsset->cred = current_cred(); 283f2a8d52eSChristian Brauner if (!nsset->cred) 284f2a8d52eSChristian Brauner goto out; 285f2a8d52eSChristian Brauner 286f2a8d52eSChristian Brauner if (nstype == CLONE_NEWNS) 287f2a8d52eSChristian Brauner nsset->fs = me->fs; 288f2a8d52eSChristian Brauner 289f2a8d52eSChristian Brauner nsset->flags = nstype; 290f2a8d52eSChristian Brauner return 0; 291f2a8d52eSChristian Brauner 292f2a8d52eSChristian Brauner out: 293f2a8d52eSChristian Brauner put_nsset(nsset); 294f2a8d52eSChristian Brauner return -ENOMEM; 295f2a8d52eSChristian Brauner } 296f2a8d52eSChristian Brauner 297f2a8d52eSChristian Brauner /* 298f2a8d52eSChristian Brauner * This is the point of no return. There are just a few namespaces 299f2a8d52eSChristian Brauner * that do some actual work here and it's sufficiently minimal that 300f2a8d52eSChristian Brauner * a separate ns_common operation seems unnecessary for now. 301f2a8d52eSChristian Brauner * Unshare is doing the same thing. If we'll end up needing to do 302f2a8d52eSChristian Brauner * more in a given namespace or a helper here is ultimately not 303f2a8d52eSChristian Brauner * exported anymore a simple commit handler for each namespace 304f2a8d52eSChristian Brauner * should be added to ns_common. 305f2a8d52eSChristian Brauner */ 306f2a8d52eSChristian Brauner static void commit_nsset(struct nsset *nsset) 307f2a8d52eSChristian Brauner { 308f2a8d52eSChristian Brauner unsigned flags = nsset->flags; 309f2a8d52eSChristian Brauner struct task_struct *me = current; 310f2a8d52eSChristian Brauner 311f2a8d52eSChristian Brauner #ifdef CONFIG_USER_NS 312f2a8d52eSChristian Brauner if (flags & CLONE_NEWUSER) { 313f2a8d52eSChristian Brauner /* transfer ownership */ 314f2a8d52eSChristian Brauner commit_creds(nsset_cred(nsset)); 315f2a8d52eSChristian Brauner nsset->cred = NULL; 316f2a8d52eSChristian Brauner } 317f2a8d52eSChristian Brauner #endif 318f2a8d52eSChristian Brauner 319f2a8d52eSChristian Brauner #ifdef CONFIG_IPC_NS 320f2a8d52eSChristian Brauner if (flags & CLONE_NEWIPC) 321f2a8d52eSChristian Brauner exit_sem(me); 322f2a8d52eSChristian Brauner #endif 323f2a8d52eSChristian Brauner 324f2a8d52eSChristian Brauner /* transfer ownership */ 325f2a8d52eSChristian Brauner switch_task_namespaces(me, nsset->nsproxy); 326f2a8d52eSChristian Brauner nsset->nsproxy = NULL; 327f2a8d52eSChristian Brauner } 328f2a8d52eSChristian Brauner 3290663c6f8SEric W. Biederman SYSCALL_DEFINE2(setns, int, fd, int, nstype) 3300663c6f8SEric W. Biederman { 3310663c6f8SEric W. Biederman struct file *file; 33233c42940SAl Viro struct ns_common *ns; 333f2a8d52eSChristian Brauner struct nsset nsset = {}; 3340663c6f8SEric W. Biederman int err; 3350663c6f8SEric W. Biederman 3360663c6f8SEric W. Biederman file = proc_ns_fget(fd); 3370663c6f8SEric W. Biederman if (IS_ERR(file)) 3380663c6f8SEric W. Biederman return PTR_ERR(file); 3390663c6f8SEric W. Biederman 3400663c6f8SEric W. Biederman err = -EINVAL; 341f77c8014SAl Viro ns = get_proc_ns(file_inode(file)); 34233c42940SAl Viro if (nstype && (ns->ops->type != nstype)) 3430663c6f8SEric W. Biederman goto out; 3440663c6f8SEric W. Biederman 345f2a8d52eSChristian Brauner err = prepare_nsset(ns->ops->type, &nsset); 346f2a8d52eSChristian Brauner if (err) 3470663c6f8SEric W. Biederman goto out; 3480663c6f8SEric W. Biederman 349f2a8d52eSChristian Brauner err = ns->ops->install(&nsset, ns); 350f2a8d52eSChristian Brauner if (!err) { 351f2a8d52eSChristian Brauner commit_nsset(&nsset); 352f2a8d52eSChristian Brauner perf_event_namespaces(current); 3530663c6f8SEric W. Biederman } 354f2a8d52eSChristian Brauner put_nsset(&nsset); 3550663c6f8SEric W. Biederman out: 3560663c6f8SEric W. Biederman fput(file); 3570663c6f8SEric W. Biederman return err; 3580663c6f8SEric W. Biederman } 3590663c6f8SEric W. Biederman 36066577193SAl Viro int __init nsproxy_cache_init(void) 36198c0d07cSCedric Le Goater { 362db8906daSPavel Emelyanov nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC); 36398c0d07cSCedric Le Goater return 0; 36498c0d07cSCedric Le Goater } 365