0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. From d0c6bedb9c49fdd994f469309a4e2668134b4e5e Mon Sep 17 00:00:00 2001
  2. From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
  3. Date: Mon, 16 Sep 2019 04:53:20 +0200
  4. Subject: [PATCH 1/3] ZEN: Add sysctl and CONFIG to disallow unprivileged
  5. CLONE_NEWUSER
  6. Our default behavior continues to match the vanilla kernel.
  7. ---
  8. include/linux/user_namespace.h | 4 ++++
  9. init/Kconfig | 16 ++++++++++++++++
  10. kernel/fork.c | 14 ++++++++++++++
  11. kernel/sysctl.c | 12 ++++++++++++
  12. kernel/user_namespace.c | 7 +++++++
  13. 5 files changed, 53 insertions(+)
  14. diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
  15. index 6030a8235617..60b7fe5fa74a 100644
  16. --- a/include/linux/user_namespace.h
  17. +++ b/include/linux/user_namespace.h
  18. @@ -156,6 +156,8 @@ static inline void set_userns_rlimit_max(struct user_namespace *ns,
  19. #ifdef CONFIG_USER_NS
  20. +extern int unprivileged_userns_clone;
  21. +
  22. static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
  23. {
  24. if (ns)
  25. @@ -189,6 +191,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns);
  26. struct ns_common *ns_get_owner(struct ns_common *ns);
  27. #else
  28. +#define unprivileged_userns_clone 0
  29. +
  30. static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
  31. {
  32. return &init_user_ns;
  33. diff --git a/init/Kconfig b/init/Kconfig
  34. index 9ffb103fc927..f91ccd3c1456 100644
  35. --- a/init/Kconfig
  36. +++ b/init/Kconfig
  37. @@ -1226,6 +1226,22 @@ config USER_NS
  38. If unsure, say N.
  39. +config USER_NS_UNPRIVILEGED
  40. + bool "Allow unprivileged users to create namespaces"
  41. + default y
  42. + depends on USER_NS
  43. + help
  44. + When disabled, unprivileged users will not be able to create
  45. + new namespaces. Allowing users to create their own namespaces
  46. + has been part of several recent local privilege escalation
  47. + exploits, so if you need user namespaces but are
  48. + paranoid^Wsecurity-conscious you want to disable this.
  49. +
  50. + This setting can be overridden at runtime via the
  51. + kernel.unprivileged_userns_clone sysctl.
  52. +
  53. + If unsure, say Y.
  54. +
  55. config PID_NS
  56. bool "PID Namespaces"
  57. default y
  58. diff --git a/kernel/fork.c b/kernel/fork.c
  59. index 10917c3e1f03..458360cf9bfb 100644
  60. --- a/kernel/fork.c
  61. +++ b/kernel/fork.c
  62. @@ -100,6 +100,10 @@
  63. #include <linux/user_events.h>
  64. #include <linux/iommu.h>
  65. +#ifdef CONFIG_USER_NS
  66. +#include <linux/user_namespace.h>
  67. +#endif
  68. +
  69. #include <asm/pgalloc.h>
  70. #include <linux/uaccess.h>
  71. #include <asm/mmu_context.h>
  72. @@ -2265,6 +2269,10 @@ __latent_entropy struct task_struct *copy_process(
  73. if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
  74. return ERR_PTR(-EINVAL);
  75. + if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
  76. + if (!capable(CAP_SYS_ADMIN))
  77. + return ERR_PTR(-EPERM);
  78. +
  79. /*
  80. * Thread groups must share signals as well, and detached threads
  81. * can only be started up within the thread group.
  82. @@ -3411,6 +3419,12 @@ int ksys_unshare(unsigned long unshare_flags)
  83. if (unshare_flags & CLONE_NEWNS)
  84. unshare_flags |= CLONE_FS;
  85. + if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
  86. + err = -EPERM;
  87. + if (!capable(CAP_SYS_ADMIN))
  88. + goto bad_unshare_out;
  89. + }
  90. +
  91. err = check_unshare_flags(unshare_flags);
  92. if (err)
  93. goto bad_unshare_out;
  94. diff --git a/kernel/sysctl.c b/kernel/sysctl.c
  95. index 157f7ce2942d..881fc4f5d61e 100644
  96. --- a/kernel/sysctl.c
  97. +++ b/kernel/sysctl.c
  98. @@ -80,6 +80,9 @@
  99. #ifdef CONFIG_RT_MUTEXES
  100. #include <linux/rtmutex.h>
  101. #endif
  102. +#ifdef CONFIG_USER_NS
  103. +#include <linux/user_namespace.h>
  104. +#endif
  105. /* shared constants to be used in various sysctls */
  106. const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 };
  107. @@ -1623,6 +1626,15 @@ static struct ctl_table kern_table[] = {
  108. .mode = 0644,
  109. .proc_handler = proc_dointvec,
  110. },
  111. +#ifdef CONFIG_USER_NS
  112. + {
  113. + .procname = "unprivileged_userns_clone",
  114. + .data = &unprivileged_userns_clone,
  115. + .maxlen = sizeof(int),
  116. + .mode = 0644,
  117. + .proc_handler = proc_dointvec,
  118. + },
  119. +#endif
  120. #ifdef CONFIG_PROC_SYSCTL
  121. {
  122. .procname = "tainted",
  123. diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
  124. index eabe8bcc7042..ac9d1f702086 100644
  125. --- a/kernel/user_namespace.c
  126. +++ b/kernel/user_namespace.c
  127. @@ -22,6 +22,13 @@
  128. #include <linux/bsearch.h>
  129. #include <linux/sort.h>
  130. +/* sysctl */
  131. +#ifdef CONFIG_USER_NS_UNPRIVILEGED
  132. +int unprivileged_userns_clone = 1;
  133. +#else
  134. +int unprivileged_userns_clone;
  135. +#endif
  136. +
  137. static struct kmem_cache *user_ns_cachep __ro_after_init;
  138. static DEFINE_MUTEX(userns_state_mutex);
  139. --
  140. 2.43.0