public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
From: DJ Delorie <dj@sourceware.org>
To: glibc-cvs@sourceware.org
Subject: [glibc] test-container: return UNSUPPORTED for ENOSPC on clone()
Date: Wed,  6 Jul 2022 02:35:24 +0000 (GMT)	[thread overview]
Message-ID: <20220706023524.49069385415A@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=bd0b58837c7df091046e7531642f379a52e1e157

commit bd0b58837c7df091046e7531642f379a52e1e157
Author: Xi Ruoyao <xry111@xry111.site>
Date:   Tue Jun 28 18:44:03 2022 +0800

    test-container: return UNSUPPORTED for ENOSPC on clone()
    
    Since Linux 4.9, the kernel provides
    /proc/sys/user/max_{mnt,pid,user}_namespace as a limitation of number of
    namespaces.  Some distros (for example, Slint Linux 14.2.1) set them (or
    only max_user_namespace) to zero as a "security policy" for disabling
    namespaces.
    
    The clone() call will set errno to ENOSPC under such a limitation.  We
    didn't check ENOSPC in the code so the test will FAIL, and report:
    
        unable to unshare user/fs: No space left on device
    
    This message is, unfortunately, very unhelpful.  It leads people to
    check the memory or disk space, instead of finding the real issue.
    
    To improve the situation, we should check for ENOSPC and return
    UNSUPPORTED as the test result.  Also refactor check_for_unshare_hints()
    to emit a proper message telling people how to make the test work, if
    they really need to run the namespaced tests.
    
    Reported-by: Philippe Delavalade <philippe.delavalade@orange.fr>
    URL: https://lists.linuxfromscratch.org/sympa/arc/lfs-support/2022-06/msg00022.html
    Signed-off-by: Xi Ruoyao <xry111@xry111.site>
    Reviewed-by: DJ Delorie <dj@redhat.com>

Diff:
---
 support/test-container.c | 67 ++++++++++++++++++++++++++----------------------
 1 file changed, 36 insertions(+), 31 deletions(-)

diff --git a/support/test-container.c b/support/test-container.c
index 7557aac441..b6a1158ae1 100644
--- a/support/test-container.c
+++ b/support/test-container.c
@@ -18,6 +18,7 @@
 
 #define _FILE_OFFSET_BITS 64
 
+#include <array_length.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -684,39 +685,43 @@ rsync (char *src, char *dest, int and_delete, int force_copies)
 /* See if we can detect what the user needs to do to get unshare
    support working for us.  */
 void
-check_for_unshare_hints (void)
+check_for_unshare_hints (int require_pidns)
 {
+  static struct {
+    const char *path;
+    int bad_value, good_value, for_pidns;
+  } files[] = {
+    /* Default Debian Linux disables user namespaces, but allows a way
+       to enable them.  */
+    { "/proc/sys/kernel/unprivileged_userns_clone", 0, 1, 0 },
+    /* ALT Linux has an alternate way of doing the same.  */
+    { "/proc/sys/kernel/userns_restrict", 1, 0, 0 },
+    /* Linux kernel >= 4.9 has a configurable limit on the number of
+       each namespace.  Some distros set the limit to zero to disable the
+       corresponding namespace as a "security policy".  */
+    { "/proc/sys/user/max_user_namespaces", 0, 1024, 0 },
+    { "/proc/sys/user/max_mnt_namespaces", 0, 1024, 0 },
+    { "/proc/sys/user/max_pid_namespaces", 0, 1024, 1 },
+  };
   FILE *f;
-  int i;
+  int i, val;
 
-  /* Default Debian Linux disables user namespaces, but allows a way
-     to enable them.  */
-  f = fopen ("/proc/sys/kernel/unprivileged_userns_clone", "r");
-  if (f != NULL)
+  for (i = 0; i < array_length (files); i++)
     {
-      i = 99; /* Sentinel.  */
-      fscanf (f, "%d", &i);
-      if (i == 0)
-	{
-	  printf ("To enable test-container, please run this as root:\n");
-	  printf ("  echo 1 > /proc/sys/kernel/unprivileged_userns_clone\n");
-	}
-      fclose (f);
-      return;
-    }
+      if (!require_pidns && files[i].for_pidns)
+        continue;
 
-  /* ALT Linux has an alternate way of doing the same.  */
-  f = fopen ("/proc/sys/kernel/userns_restrict", "r");
-  if (f != NULL)
-    {
-      i = 99; /* Sentinel.  */
-      fscanf (f, "%d", &i);
-      if (i == 1)
-	{
-	  printf ("To enable test-container, please run this as root:\n");
-	  printf ("  echo 0 > /proc/sys/kernel/userns_restrict\n");
-	}
-      fclose (f);
+      f = fopen (files[i].path, "r");
+      if (f == NULL)
+        continue;
+
+      val = -1; /* Sentinel.  */
+      fscanf (f, "%d", &val);
+      if (val != files[i].bad_value)
+	continue;
+
+      printf ("To enable test-container, please run this as root:\n");
+      printf ("  echo %d > %s\n", files[i].good_value, files[i].path);
       return;
     }
 }
@@ -1117,11 +1122,11 @@ main (int argc, char **argv)
     {
       /* Older kernels may not support all the options, or security
 	 policy may block this call.  */
-      if (errno == EINVAL || errno == EPERM)
+      if (errno == EINVAL || errno == EPERM || errno == ENOSPC)
 	{
 	  int saved_errno = errno;
-	  if (errno == EPERM)
-	    check_for_unshare_hints ();
+	  if (errno == EPERM || errno == ENOSPC)
+	    check_for_unshare_hints (require_pidns);
 	  FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (saved_errno));
 	}
       /* We're about to exit anyway, it's "safe" to call unshare again


                 reply	other threads:[~2022-07-06  2:35 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220706023524.49069385415A@sourceware.org \
    --to=dj@sourceware.org \
    --cc=glibc-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).