nsproxy.c (75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37) | nsproxy.c (769071ac9f20b6a447410c7eaa55d1a5233ef40c) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2006 IBM Corporation 4 * 5 * Author: Serge Hallyn <serue@us.ibm.com> 6 * 7 * Jun 2006 - namespaces support 8 * OpenVZ, SWsoft Inc. --- 4 unchanged lines hidden (view full) --- 13#include <linux/export.h> 14#include <linux/nsproxy.h> 15#include <linux/init_task.h> 16#include <linux/mnt_namespace.h> 17#include <linux/utsname.h> 18#include <linux/pid_namespace.h> 19#include <net/net_namespace.h> 20#include <linux/ipc_namespace.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2006 IBM Corporation 4 * 5 * Author: Serge Hallyn <serue@us.ibm.com> 6 * 7 * Jun 2006 - namespaces support 8 * OpenVZ, SWsoft Inc. --- 4 unchanged lines hidden (view full) --- 13#include <linux/export.h> 14#include <linux/nsproxy.h> 15#include <linux/init_task.h> 16#include <linux/mnt_namespace.h> 17#include <linux/utsname.h> 18#include <linux/pid_namespace.h> 19#include <net/net_namespace.h> 20#include <linux/ipc_namespace.h> |
21#include <linux/time_namespace.h> |
|
21#include <linux/proc_ns.h> 22#include <linux/file.h> 23#include <linux/syscalls.h> 24#include <linux/cgroup.h> 25#include <linux/perf_event.h> 26 27static struct kmem_cache *nsproxy_cachep; 28 --- 6 unchanged lines hidden (view full) --- 35 .mnt_ns = NULL, 36 .pid_ns_for_children = &init_pid_ns, 37#ifdef CONFIG_NET 38 .net_ns = &init_net, 39#endif 40#ifdef CONFIG_CGROUPS 41 .cgroup_ns = &init_cgroup_ns, 42#endif | 22#include <linux/proc_ns.h> 23#include <linux/file.h> 24#include <linux/syscalls.h> 25#include <linux/cgroup.h> 26#include <linux/perf_event.h> 27 28static struct kmem_cache *nsproxy_cachep; 29 --- 6 unchanged lines hidden (view full) --- 36 .mnt_ns = NULL, 37 .pid_ns_for_children = &init_pid_ns, 38#ifdef CONFIG_NET 39 .net_ns = &init_net, 40#endif 41#ifdef CONFIG_CGROUPS 42 .cgroup_ns = &init_cgroup_ns, 43#endif |
44#ifdef CONFIG_TIME_NS 45 .time_ns = &init_time_ns, 46 .time_ns_for_children = &init_time_ns, 47#endif |
|
43}; 44 45static inline struct nsproxy *create_nsproxy(void) 46{ 47 struct nsproxy *nsproxy; 48 49 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL); 50 if (nsproxy) --- 50 unchanged lines hidden (view full) --- 101 } 102 103 new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns); 104 if (IS_ERR(new_nsp->net_ns)) { 105 err = PTR_ERR(new_nsp->net_ns); 106 goto out_net; 107 } 108 | 48}; 49 50static inline struct nsproxy *create_nsproxy(void) 51{ 52 struct nsproxy *nsproxy; 53 54 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL); 55 if (nsproxy) --- 50 unchanged lines hidden (view full) --- 106 } 107 108 new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns); 109 if (IS_ERR(new_nsp->net_ns)) { 110 err = PTR_ERR(new_nsp->net_ns); 111 goto out_net; 112 } 113 |
114 new_nsp->time_ns_for_children = copy_time_ns(flags, user_ns, 115 tsk->nsproxy->time_ns_for_children); 116 if (IS_ERR(new_nsp->time_ns_for_children)) { 117 err = PTR_ERR(new_nsp->time_ns_for_children); 118 goto out_time; 119 } 120 new_nsp->time_ns = get_time_ns(tsk->nsproxy->time_ns); 121 |
|
109 return new_nsp; 110 | 122 return new_nsp; 123 |
124out_time: 125 put_net(new_nsp->net_ns); |
|
111out_net: 112 put_cgroup_ns(new_nsp->cgroup_ns); 113out_cgroup: 114 if (new_nsp->pid_ns_for_children) 115 put_pid_ns(new_nsp->pid_ns_for_children); 116out_pid: 117 if (new_nsp->ipc_ns) 118 put_ipc_ns(new_nsp->ipc_ns); --- 12 unchanged lines hidden (view full) --- 131 * called from clone. This now handles copy for nsproxy and all 132 * namespaces therein. 133 */ 134int copy_namespaces(unsigned long flags, struct task_struct *tsk) 135{ 136 struct nsproxy *old_ns = tsk->nsproxy; 137 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); 138 struct nsproxy *new_ns; | 126out_net: 127 put_cgroup_ns(new_nsp->cgroup_ns); 128out_cgroup: 129 if (new_nsp->pid_ns_for_children) 130 put_pid_ns(new_nsp->pid_ns_for_children); 131out_pid: 132 if (new_nsp->ipc_ns) 133 put_ipc_ns(new_nsp->ipc_ns); --- 12 unchanged lines hidden (view full) --- 146 * called from clone. This now handles copy for nsproxy and all 147 * namespaces therein. 148 */ 149int copy_namespaces(unsigned long flags, struct task_struct *tsk) 150{ 151 struct nsproxy *old_ns = tsk->nsproxy; 152 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns); 153 struct nsproxy *new_ns; |
154 int ret; |
|
139 140 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 141 CLONE_NEWPID | CLONE_NEWNET | | 155 156 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 157 CLONE_NEWPID | CLONE_NEWNET | |
142 CLONE_NEWCGROUP)))) { 143 get_nsproxy(old_ns); 144 return 0; 145 } 146 147 if (!ns_capable(user_ns, CAP_SYS_ADMIN)) | 158 CLONE_NEWCGROUP | CLONE_NEWTIME)))) { 159 if (likely(old_ns->time_ns_for_children == old_ns->time_ns)) { 160 get_nsproxy(old_ns); 161 return 0; 162 } 163 } else if (!ns_capable(user_ns, CAP_SYS_ADMIN)) |
148 return -EPERM; 149 150 /* 151 * CLONE_NEWIPC must detach from the undolist: after switching 152 * to a new ipc namespace, the semaphore arrays from the old 153 * namespace are unreachable. In clone parlance, CLONE_SYSVSEM 154 * means share undolist with parent, so we must forbid using 155 * it along with CLONE_NEWIPC. 156 */ 157 if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == 158 (CLONE_NEWIPC | CLONE_SYSVSEM)) 159 return -EINVAL; 160 161 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); 162 if (IS_ERR(new_ns)) 163 return PTR_ERR(new_ns); 164 | 164 return -EPERM; 165 166 /* 167 * CLONE_NEWIPC must detach from the undolist: after switching 168 * to a new ipc namespace, the semaphore arrays from the old 169 * namespace are unreachable. In clone parlance, CLONE_SYSVSEM 170 * means share undolist with parent, so we must forbid using 171 * it along with CLONE_NEWIPC. 172 */ 173 if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) == 174 (CLONE_NEWIPC | CLONE_SYSVSEM)) 175 return -EINVAL; 176 177 new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs); 178 if (IS_ERR(new_ns)) 179 return PTR_ERR(new_ns); 180 |
181 ret = timens_on_fork(new_ns, tsk); 182 if (ret) { 183 free_nsproxy(new_ns); 184 return ret; 185 } 186 |
|
165 tsk->nsproxy = new_ns; 166 return 0; 167} 168 169void free_nsproxy(struct nsproxy *ns) 170{ 171 if (ns->mnt_ns) 172 put_mnt_ns(ns->mnt_ns); 173 if (ns->uts_ns) 174 put_uts_ns(ns->uts_ns); 175 if (ns->ipc_ns) 176 put_ipc_ns(ns->ipc_ns); 177 if (ns->pid_ns_for_children) 178 put_pid_ns(ns->pid_ns_for_children); | 187 tsk->nsproxy = new_ns; 188 return 0; 189} 190 191void free_nsproxy(struct nsproxy *ns) 192{ 193 if (ns->mnt_ns) 194 put_mnt_ns(ns->mnt_ns); 195 if (ns->uts_ns) 196 put_uts_ns(ns->uts_ns); 197 if (ns->ipc_ns) 198 put_ipc_ns(ns->ipc_ns); 199 if (ns->pid_ns_for_children) 200 put_pid_ns(ns->pid_ns_for_children); |
201 if (ns->time_ns) 202 put_time_ns(ns->time_ns); 203 if (ns->time_ns_for_children) 204 put_time_ns(ns->time_ns_for_children); |
|
179 put_cgroup_ns(ns->cgroup_ns); 180 put_net(ns->net_ns); 181 kmem_cache_free(nsproxy_cachep, ns); 182} 183 184/* 185 * Called from unshare. Unshare all the namespaces part of nsproxy. 186 * On success, returns the new nsproxy. 187 */ 188int unshare_nsproxy_namespaces(unsigned long unshare_flags, 189 struct nsproxy **new_nsp, struct cred *new_cred, struct fs_struct *new_fs) 190{ 191 struct user_namespace *user_ns; 192 int err = 0; 193 194 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | | 205 put_cgroup_ns(ns->cgroup_ns); 206 put_net(ns->net_ns); 207 kmem_cache_free(nsproxy_cachep, ns); 208} 209 210/* 211 * Called from unshare. Unshare all the namespaces part of nsproxy. 212 * On success, returns the new nsproxy. 213 */ 214int unshare_nsproxy_namespaces(unsigned long unshare_flags, 215 struct nsproxy **new_nsp, struct cred *new_cred, struct fs_struct *new_fs) 216{ 217 struct user_namespace *user_ns; 218 int err = 0; 219 220 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
195 CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP))) | 221 CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP | 222 CLONE_NEWTIME))) |
196 return 0; 197 198 user_ns = new_cred ? new_cred->user_ns : current_user_ns(); 199 if (!ns_capable(user_ns, CAP_SYS_ADMIN)) 200 return -EPERM; 201 202 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns, 203 new_fs ? new_fs : current->fs); --- 70 unchanged lines hidden --- | 223 return 0; 224 225 user_ns = new_cred ? new_cred->user_ns : current_user_ns(); 226 if (!ns_capable(user_ns, CAP_SYS_ADMIN)) 227 return -EPERM; 228 229 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns, 230 new_fs ? new_fs : current->fs); --- 70 unchanged lines hidden --- |