ns_cgroup.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * ns_cgroup.c - namespace cgroup subsystem
  3. *
  4. * Copyright 2006, 2007 IBM Corp
  5. */
  6. #include <linux/module.h>
  7. #include <linux/cgroup.h>
  8. #include <linux/fs.h>
  9. #include <linux/proc_fs.h>
  10. #include <linux/slab.h>
  11. #include <linux/nsproxy.h>
  12. struct ns_cgroup {
  13. struct cgroup_subsys_state css;
  14. };
  15. struct cgroup_subsys ns_subsys;
  16. static inline struct ns_cgroup *cgroup_to_ns(
  17. struct cgroup *cgroup)
  18. {
  19. return container_of(cgroup_subsys_state(cgroup, ns_subsys_id),
  20. struct ns_cgroup, css);
  21. }
  22. int ns_cgroup_clone(struct task_struct *task, struct pid *pid)
  23. {
  24. char name[PROC_NUMBUF];
  25. snprintf(name, PROC_NUMBUF, "%d", pid_vnr(pid));
  26. return cgroup_clone(task, &ns_subsys, name);
  27. }
  28. /*
  29. * Rules:
  30. * 1. you can only enter a cgroup which is a descendant of your current
  31. * cgroup
  32. * 2. you can only place another process into a cgroup if
  33. * a. you have CAP_SYS_ADMIN
  34. * b. your cgroup is an ancestor of task's destination cgroup
  35. * (hence either you are in the same cgroup as task, or in an
  36. * ancestor cgroup thereof)
  37. */
  38. static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup,
  39. struct task_struct *task, bool threadgroup)
  40. {
  41. if (current != task) {
  42. if (!capable(CAP_SYS_ADMIN))
  43. return -EPERM;
  44. if (!cgroup_is_descendant(new_cgroup, current))
  45. return -EPERM;
  46. }
  47. if (!cgroup_is_descendant(new_cgroup, task))
  48. return -EPERM;
  49. if (threadgroup) {
  50. struct task_struct *c;
  51. rcu_read_lock();
  52. list_for_each_entry_rcu(c, &task->thread_group, thread_group) {
  53. if (!cgroup_is_descendant(new_cgroup, c)) {
  54. rcu_read_unlock();
  55. return -EPERM;
  56. }
  57. }
  58. rcu_read_unlock();
  59. }
  60. return 0;
  61. }
  62. /*
  63. * Rules: you can only create a cgroup if
  64. * 1. you are capable(CAP_SYS_ADMIN)
  65. * 2. the target cgroup is a descendant of your own cgroup
  66. */
  67. static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
  68. struct cgroup *cgroup)
  69. {
  70. struct ns_cgroup *ns_cgroup;
  71. if (!capable(CAP_SYS_ADMIN))
  72. return ERR_PTR(-EPERM);
  73. if (!cgroup_is_descendant(cgroup, current))
  74. return ERR_PTR(-EPERM);
  75. ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
  76. if (!ns_cgroup)
  77. return ERR_PTR(-ENOMEM);
  78. return &ns_cgroup->css;
  79. }
  80. static void ns_destroy(struct cgroup_subsys *ss,
  81. struct cgroup *cgroup)
  82. {
  83. struct ns_cgroup *ns_cgroup;
  84. ns_cgroup = cgroup_to_ns(cgroup);
  85. kfree(ns_cgroup);
  86. }
  87. struct cgroup_subsys ns_subsys = {
  88. .name = "ns",
  89. .can_attach = ns_can_attach,
  90. .create = ns_create,
  91. .destroy = ns_destroy,
  92. .subsys_id = ns_subsys_id,
  93. };