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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From d70cb56d43efddd10d4263f2af24f52fb81137b9 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 ca2ca3884f76..d9591a8a6ead 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. @@ -2171,6 +2177,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. @@ -3324,6 +3334,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 cb57da499ebb..5e9ae0e6a727 100644
  57. --- a/kernel/sysctl.c
  58. +++ b/kernel/sysctl.c
  59. @@ -135,6 +135,10 @@ static enum sysctl_writes_mode sysctl_writes_strict = SYSCTL_WRITES_STRICT;
  60. int sysctl_legacy_va_layout;
  61. #endif
  62. +#ifdef CONFIG_USER_NS
  63. +extern int unprivileged_userns_clone;
  64. +#endif
  65. +
  66. #endif /* CONFIG_SYSCTL */
  67. /*
  68. @@ -1617,6 +1621,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 aa0b2e47f2f2..222bb2b40b73 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.49.0