From patchwork Tue Jun 21 11:30:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 55231 X-Patchwork-Delegate: carlos@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EB97F3857430 for ; Tue, 21 Jun 2022 11:31:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB97F3857430 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1655811099; bh=ztvWYrYncNQfwLogyGCDqepgM+I2Q901VtaqmSJiFB8=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=nFqtMy3XdzfqWfKw6sRc/gEPQdt9FWflNyEbJozSjSFAQnb8JDcTX/QDDfxUGnA1U 62LFBd/vNd2uMwObFKxbpk22rP7KVmKLbEgvgRDqhc1mfvbE7RyAF8ZIOhwr+eA+jR /watSQUDD2GKIj/F3FN8D+plZe9yjlj1fa/PTwF4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by sourceware.org (Postfix) with ESMTPS id 3C49B3857371 for ; Tue, 21 Jun 2022 11:30:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3C49B3857371 Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id A5C5D66A7E; Tue, 21 Jun 2022 07:30:33 -0400 (EDT) Message-ID: Subject: [PATCH] test-container: return UNSUPPORTED for ENOSPC on clone() To: libc-alpha@sourceware.org Date: Tue, 21 Jun 2022 19:30:31 +0800 User-Agent: Evolution 3.44.2 MIME-Version: 1.0 X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FROM_SUSPICIOUS_NTLD, FROM_SUSPICIOUS_NTLD_FP, GIT_PATCH_0, LIKELY_SPAM_FROM, PDS_OTHER_BAD_TLD, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Xi Ruoyao via Libc-alpha From: Xi Ruoyao Reply-To: Xi Ruoyao Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 URL: https://lists.linuxfromscratch.org/sympa/arc/lfs-support/2022-06/msg00022.html Signed-off-by: Xi Ruoyao Reviewed-by: DJ Delorie --- 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..b186b75146 100644 --- a/support/test-container.c +++ b/support/test-container.c @@ -18,6 +18,7 @@ #define _FILE_OFFSET_BITS 64 +#include #include #include #include @@ -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. */ + /* ALT Linux has an alternate way of doing the same. */ + { "/proc/sys/kernel/unprivileged_userns_clone", 0, 1, 0 }, + { "/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