0001-add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From f675a2222ecd97c5b85bf05901e3220ee90c30ba Mon Sep 17 00:00:00 2001
  2. From: Serge Hallyn <serge.hallyn@canonical.com>
  3. Date: Fri, 31 May 2013 19:12:12 +0100
  4. Subject: [PATCH] add sysctl to disallow unprivileged CLONE_NEWUSER by default
  5. add sysctl to disallow unprivileged CLONE_NEWUSER by default
  6. This is a short-term patch. Unprivileged use of CLONE_NEWUSER
  7. is certainly an intended feature of user namespaces. However
  8. for at least saucy we want to make sure that, if any security
  9. issues are found, we have a fail-safe.
  10. Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
  11. [bwh: Remove unneeded binary sysctl bits]
  12. [bwh: Keep this sysctl, but change the default to enabled]
  13. ---
  14. kernel/fork.c | 16 ++++++++++++++++
  15. kernel/sysctl.c | 13 +++++++++++++
  16. kernel/user_namespace.c | 3 +++
  17. 3 files changed, 32 insertions(+)
  18. diff --git a/kernel/fork.c b/kernel/fork.c
  19. index 168681fc4b25..74abab2c65c1 100644
  20. --- a/kernel/fork.c
  21. +++ b/kernel/fork.c
  22. @@ -119,6 +119,12 @@
  23. #include <kunit/visibility.h>
  24. +#ifdef CONFIG_USER_NS
  25. +extern int unprivileged_userns_clone;
  26. +#else
  27. +#define unprivileged_userns_clone 0
  28. +#endif
  29. +
  30. /*
  31. * Minimum number of threads to boot the kernel
  32. */
  33. @@ -2194,6 +2200,10 @@ __latent_entropy struct task_struct *copy_process(
  34. if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
  35. return ERR_PTR(-EINVAL);
  36. + if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
  37. + if (!capable(CAP_SYS_ADMIN))
  38. + return ERR_PTR(-EPERM);
  39. +
  40. /*
  41. * Thread groups must share signals as well, and detached threads
  42. * can only be started up within the thread group.
  43. @@ -3354,6 +3364,12 @@ int ksys_unshare(unsigned long unshare_flags)
  44. if (unshare_flags & CLONE_NEWNS)
  45. unshare_flags |= CLONE_FS;
  46. + if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
  47. + err = -EPERM;
  48. + if (!capable(CAP_SYS_ADMIN))
  49. + goto bad_unshare_out;
  50. + }
  51. +
  52. err = check_unshare_flags(unshare_flags);
  53. if (err)
  54. goto bad_unshare_out;
  55. diff --git a/kernel/sysctl.c b/kernel/sysctl.c
  56. index 3b7a7308e35b..cb4bab6a39bf 100644
  57. --- a/kernel/sysctl.c
  58. +++ b/kernel/sysctl.c
  59. @@ -84,6 +84,10 @@ EXPORT_SYMBOL_GPL(sysctl_long_vals);
  60. static const int ngroups_max = NGROUPS_MAX;
  61. static const int cap_last_cap = CAP_LAST_CAP;
  62. +#ifdef CONFIG_USER_NS
  63. +extern int unprivileged_userns_clone;
  64. +#endif
  65. +
  66. #ifdef CONFIG_PROC_SYSCTL
  67. /**
  68. @@ -1595,6 +1599,15 @@ static const struct ctl_table kern_table[] = {
  69. .mode = 0644,
  70. .proc_handler = proc_dointvec,
  71. },
  72. +#ifdef CONFIG_USER_NS
  73. + {
  74. + .procname = "unprivileged_userns_clone",
  75. + .data = &unprivileged_userns_clone,
  76. + .maxlen = sizeof(int),
  77. + .mode = 0644,
  78. + .proc_handler = proc_dointvec,
  79. + },
  80. +#endif
  81. #ifdef CONFIG_PROC_SYSCTL
  82. {
  83. .procname = "tainted",
  84. diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
  85. index 682f40d5632d..bf265ad528f9 100644
  86. --- a/kernel/user_namespace.c
  87. +++ b/kernel/user_namespace.c
  88. @@ -22,6 +22,9 @@
  89. #include <linux/bsearch.h>
  90. #include <linux/sort.h>
  91. +/* sysctl */
  92. +int unprivileged_userns_clone = 1;
  93. +
  94. static struct kmem_cache *user_ns_cachep __ro_after_init;
  95. static DEFINE_MUTEX(userns_state_mutex);
  96. --
  97. 2.50.0