~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/cgroup/namespace.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include "cgroup-internal.h"
  3 
  4 #include <linux/sched/task.h>
  5 #include <linux/slab.h>
  6 #include <linux/nsproxy.h>
  7 #include <linux/proc_ns.h>
  8 
  9 
 10 /* cgroup namespaces */
 11 
 12 static struct ucounts *inc_cgroup_namespaces(struct user_namespace *ns)
 13 {
 14         return inc_ucount(ns, current_euid(), UCOUNT_CGROUP_NAMESPACES);
 15 }
 16 
 17 static void dec_cgroup_namespaces(struct ucounts *ucounts)
 18 {
 19         dec_ucount(ucounts, UCOUNT_CGROUP_NAMESPACES);
 20 }
 21 
 22 static struct cgroup_namespace *alloc_cgroup_ns(void)
 23 {
 24         struct cgroup_namespace *new_ns;
 25         int ret;
 26 
 27         new_ns = kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL_ACCOUNT);
 28         if (!new_ns)
 29                 return ERR_PTR(-ENOMEM);
 30         ret = ns_alloc_inum(&new_ns->ns);
 31         if (ret) {
 32                 kfree(new_ns);
 33                 return ERR_PTR(ret);
 34         }
 35         refcount_set(&new_ns->ns.count, 1);
 36         new_ns->ns.ops = &cgroupns_operations;
 37         return new_ns;
 38 }
 39 
 40 void free_cgroup_ns(struct cgroup_namespace *ns)
 41 {
 42         put_css_set(ns->root_cset);
 43         dec_cgroup_namespaces(ns->ucounts);
 44         put_user_ns(ns->user_ns);
 45         ns_free_inum(&ns->ns);
 46         kfree(ns);
 47 }
 48 EXPORT_SYMBOL(free_cgroup_ns);
 49 
 50 struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
 51                                         struct user_namespace *user_ns,
 52                                         struct cgroup_namespace *old_ns)
 53 {
 54         struct cgroup_namespace *new_ns;
 55         struct ucounts *ucounts;
 56         struct css_set *cset;
 57 
 58         BUG_ON(!old_ns);
 59 
 60         if (!(flags & CLONE_NEWCGROUP)) {
 61                 get_cgroup_ns(old_ns);
 62                 return old_ns;
 63         }
 64 
 65         /* Allow only sysadmin to create cgroup namespace. */
 66         if (!ns_capable(user_ns, CAP_SYS_ADMIN))
 67                 return ERR_PTR(-EPERM);
 68 
 69         ucounts = inc_cgroup_namespaces(user_ns);
 70         if (!ucounts)
 71                 return ERR_PTR(-ENOSPC);
 72 
 73         /* It is not safe to take cgroup_mutex here */
 74         spin_lock_irq(&css_set_lock);
 75         cset = task_css_set(current);
 76         get_css_set(cset);
 77         spin_unlock_irq(&css_set_lock);
 78 
 79         new_ns = alloc_cgroup_ns();
 80         if (IS_ERR(new_ns)) {
 81                 put_css_set(cset);
 82                 dec_cgroup_namespaces(ucounts);
 83                 return new_ns;
 84         }
 85 
 86         new_ns->user_ns = get_user_ns(user_ns);
 87         new_ns->ucounts = ucounts;
 88         new_ns->root_cset = cset;
 89 
 90         return new_ns;
 91 }
 92 
 93 static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns)
 94 {
 95         return container_of(ns, struct cgroup_namespace, ns);
 96 }
 97 
 98 static int cgroupns_install(struct nsset *nsset, struct ns_common *ns)
 99 {
100         struct nsproxy *nsproxy = nsset->nsproxy;
101         struct cgroup_namespace *cgroup_ns = to_cg_ns(ns);
102 
103         if (!ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN) ||
104             !ns_capable(cgroup_ns->user_ns, CAP_SYS_ADMIN))
105                 return -EPERM;
106 
107         /* Don't need to do anything if we are attaching to our own cgroupns. */
108         if (cgroup_ns == nsproxy->cgroup_ns)
109                 return 0;
110 
111         get_cgroup_ns(cgroup_ns);
112         put_cgroup_ns(nsproxy->cgroup_ns);
113         nsproxy->cgroup_ns = cgroup_ns;
114 
115         return 0;
116 }
117 
118 static struct ns_common *cgroupns_get(struct task_struct *task)
119 {
120         struct cgroup_namespace *ns = NULL;
121         struct nsproxy *nsproxy;
122 
123         task_lock(task);
124         nsproxy = task->nsproxy;
125         if (nsproxy) {
126                 ns = nsproxy->cgroup_ns;
127                 get_cgroup_ns(ns);
128         }
129         task_unlock(task);
130 
131         return ns ? &ns->ns : NULL;
132 }
133 
134 static void cgroupns_put(struct ns_common *ns)
135 {
136         put_cgroup_ns(to_cg_ns(ns));
137 }
138 
139 static struct user_namespace *cgroupns_owner(struct ns_common *ns)
140 {
141         return to_cg_ns(ns)->user_ns;
142 }
143 
144 const struct proc_ns_operations cgroupns_operations = {
145         .name           = "cgroup",
146         .type           = CLONE_NEWCGROUP,
147         .get            = cgroupns_get,
148         .put            = cgroupns_put,
149         .install        = cgroupns_install,
150         .owner          = cgroupns_owner,
151 };
152 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php