From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on starla X-Spam-Level: X-Spam-Status: No, score=-1.4 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id E49B61F44D for ; Wed, 20 Mar 2024 09:32:14 +0000 (UTC) Authentication-Results: dcvr.yhbt.net; dkim=pass (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=U6q6E27j; dkim-atps=neutral Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 105F0385842E for ; Wed, 20 Mar 2024 09:32:13 +0000 (GMT) Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by sourceware.org (Postfix) with ESMTPS id 9D16E3858D1E for ; Wed, 20 Mar 2024 09:31:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9D16E3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=canonical.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9D16E3858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710927111; cv=none; b=ucYmhKLigp/PrCQPZbOybujZ8dWjFQm685tIW+JcHYhXHbXk7JzArOp4sVSPl43TL135ba5fKpml8UMrUnPMGDhqxuAbX9Iw0RNRO7HDdKQPlT0On+xNO3pE8p/wuJvOP9sRm8yTTjX/b27mIjg6opQp/JNg3m/3a6e0kv02t7s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710927111; c=relaxed/simple; bh=Diy48kHABn0RNZS+oKiVZ0UmKU0DmTY9Ee7NtrK8L/c=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Scn7GMqBuL4O8xyshSJjDTBIX1txzVqW2OwZ/1E+Q432xARJciSN0Og/cwy8GD0xUShQD3l+S1tTi/iBLZ5E93b15/XF+wu/KdJbdTH5caOLViJGhpwrFPapN6JjGQ3ObzSsUP9lppWFA6eU7+gt1nzeA6JjisNLClz2bd2Im5g= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from mail-lf1-f69.google.com (mail-lf1-f69.google.com [209.85.167.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id A8A1F3F0F8 for ; Wed, 20 Mar 2024 09:31:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1710927107; bh=VYOO24mkVt0GXLJydU4sSq/yGoKGaW06Qzto9eoOuJI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=U6q6E27j7driq39IEpeuE3QuEFtiRhiD1wAWkyrgmiEgFwbCTR0LIiy0/B5LEx5kX UivQZ+doRThZwqLNjiEPOi0tFuMGWJRNw7nZeizJ6Ve7n3lMnLBve8CaRc91Yb7RIk 27/+ZjBU33/QLxbwH7XCCgFSf9OTHN5J5KL42xOHjt9++xvdUHIg3dKgTAJkZrI6GT w5TQMMuQxOkLE3LntSJ2JHOUK4exldWYBpdiYHuSCtQ4VG5FoblmNEgiY2VewJqIIq 4Eidrk9PL6rKbElkB1M4GRzNmM+MUaAjEBuVz5BGud130rYUddrUDIFrjqazC8B3F9 AcxedVL1T7YZA== Received: by mail-lf1-f69.google.com with SMTP id 2adb3069b0e04-5158aeaa2abso308590e87.0 for ; Wed, 20 Mar 2024 02:31:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710927106; x=1711531906; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VYOO24mkVt0GXLJydU4sSq/yGoKGaW06Qzto9eoOuJI=; b=o1sfPzb1F3VSLjpgquMfWNE4Rei0zPCdDPVcU+Schu3+t3V1D7GCGhatONhFOI5IhC nioubNHNC2ukvG0XYmR5qOy2N12hE7ST3CiMrb4escpuD5s4o39T0bOWefVQ4lnOzU22 aMBmpwqd3jMs2ERxhm03+8clTrc53AZPkVq5AChKvGhqIBIV31sOjR/aUxx1P915D2cV pts03imLz2UskWd15kGvjHRdfP9nKJRWZDwG4xzV+0RvyKyZspW8rxNMSiN/iUt/bCYt Fevw5m/7qEQ2B452Az70ikqU126sQsR2bAIA7yF+C9AYc7EP34XZDATftZHUTf969LGS T9IQ== X-Gm-Message-State: AOJu0Yzyxp2bggXAfIqgzkiYDdI9HzU+Z/BRnip/0O5Rm+hpzYypwk0G UFSHMf8zJj83DxXxo/gSt8KOuwWuNWJgzJzLIRYCz1af6krxKBcs+LMxbNO7wYCLVusyhmGQDjs SaI4XeG2NQE/+EDdFn4PJ4s0l55LCLZ1SFWEqBUfriK3WvwUKkkRso09ZzM/pxbihZSRNwjFrUa pnYHLXMA== X-Received: by 2002:ac2:5306:0:b0:513:80cd:e807 with SMTP id c6-20020ac25306000000b0051380cde807mr3578393lfh.20.1710927106552; Wed, 20 Mar 2024 02:31:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEyPtFY46JX4bMHGR62q5Mb0WR8ZQn45QBZRW1yh2yihcj72vq9PwJ4nTBXt1oYg18tBMW1dA== X-Received: by 2002:ac2:5306:0:b0:513:80cd:e807 with SMTP id c6-20020ac25306000000b0051380cde807mr3578382lfh.20.1710927106130; Wed, 20 Mar 2024 02:31:46 -0700 (PDT) Received: from localhost ([2a01:e0a:169:7380:c492:ee4d:b2ff:68ad]) by smtp.gmail.com with ESMTPSA id o30-20020a05600c511e00b004146a884bffsm1602249wms.18.2024.03.20.02.31.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Mar 2024 02:31:45 -0700 (PDT) From: Simon Chopin To: libc-alpha@sourceware.org Cc: Simon Chopin Subject: [PATCH] tests: handle AppArmor userns mitigation Date: Wed, 20 Mar 2024 10:31:35 +0100 Message-ID: <20240320093135.74043-1-simon.chopin@canonical.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+e=80x24.org@sourceware.org Support for flat denial of user namespace creation from AppArmor was added in commit 59e0441d4a ("tests: gracefully handle AppArmor userns containment"). However, AppArmor supports another mode where it allows the namespace creation but denies privileged actions within that namespace. The mitigation mode will be enabled by default in Ubuntu 24.04. This patch adds support for properly skipping the tests when that happens (usually when calling mount() or writing to /proc/self/uid_map) Further info: * AppArmor user namespace restriction modes: https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_userns_restriction#two-types-of-restrictions * Error codes for AppArmor-denied syscals: https://gitlab.com/apparmor/apparmor/-/wikis/manpage_apparmor.d.5#profile-mode Signed-off-by: Simon Chopin --- support/support_become_root.c | 41 ++++++++++++++----- support/test-container.c | 12 +++++- .../unix/sysv/linux/tst-getcwd-smallbuff.c | 17 +++++--- sysdeps/unix/sysv/linux/tst-pidfd_getpid.c | 2 +- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/support/support_become_root.c b/support/support_become_root.c index 5920fc8236..f744886037 100644 --- a/support/support_become_root.c +++ b/support/support_become_root.c @@ -28,6 +28,34 @@ #include #ifdef CLONE_NEWUSER +static void +write_id_map (int map_fd, unsigned long long src, + unsigned long long dst, unsigned long long range) +{ + char map_buf[100]; + int size = snprintf (map_buf, sizeof (map_buf), "%llu %llu %llu\n", src, dst, + range); + TEST_VERIFY_EXIT (size < sizeof (map_buf)); + int ret = write (map_fd, map_buf, size); + if (ret < 0) + { + if (errno == EPERM || errno == EACCES) + { + /* Likely a LSM deny. */ + FAIL_UNSUPPORTED ( + "Could not write ID map file, check security settings: %m\n"); + } + else + FAIL_EXIT1 ("Could not write ID map file: %m\n"); + } + else if (ret < size) + { + /* Retrying would just fail with EPERM, see user_namespaces(7). */ + FAIL_EXIT1 ( + "couldn't write the entire buffer at once to the ID file: %m\n"); + } +} + /* The necessary steps to allow file creation in user namespaces. */ static void setup_uid_gid_mapping (uid_t original_uid, gid_t original_gid) @@ -43,12 +71,7 @@ setup_uid_gid_mapping (uid_t original_uid, gid_t original_gid) /* We map our original UID to the same UID in the container so we own our own files normally. Without that, file creation could fail with EOVERFLOW (sic!). */ - char buf[100]; - int ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n", - (unsigned long long) original_uid, - (unsigned long long) original_uid); - TEST_VERIFY_EXIT (ret < sizeof (buf)); - xwrite (fd, buf, ret); + write_id_map (fd, original_uid, original_uid, 1); xclose (fd); /* Linux 3.19 introduced the setgroups file. We need write "deny" to this @@ -69,11 +92,7 @@ setup_uid_gid_mapping (uid_t original_uid, gid_t original_gid) /* Now map our own GID, like we did for the user ID. */ fd = xopen ("/proc/self/gid_map", O_WRONLY, 0); - ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n", - (unsigned long long) original_gid, - (unsigned long long) original_gid); - TEST_VERIFY_EXIT (ret < sizeof (buf)); - xwrite (fd, buf, ret); + write_id_map (fd, original_gid, original_gid, 1); xclose (fd); } #endif /* CLONE_NEWUSER */ diff --git a/support/test-container.c b/support/test-container.c index ebcc722da5..fd45cbfa57 100644 --- a/support/test-container.c +++ b/support/test-container.c @@ -1133,7 +1133,17 @@ main (int argc, char **argv) /* Some systems, by default, all mounts leak out of the namespace. */ if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0) - FAIL_EXIT1 ("could not create a private mount namespace\n"); + { + int saved_errno = errno; + if (errno == EPERM || errno == EACCES) + { + check_for_unshare_hints (require_pidns); + FAIL_UNSUPPORTED ("could not create a private mount namespace " + "(security policy?: %s)", + strerror (saved_errno)); + } + FAIL_EXIT1 ("could not create a private mount namespace\n"); + } trymount (support_srcdir_root, new_srcdir_path); trymount (support_objdir_root, new_objdir_path); diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c index 55362f6060..f564be6a63 100644 --- a/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c +++ b/sysdeps/unix/sysv/linux/tst-getcwd-smallbuff.c @@ -133,7 +133,13 @@ child_func (void * const arg) TEST_VERIFY_EXIT (ch == '1'); if (mount ("/", MOUNT_NAME, NULL, MS_BIND | MS_REC, NULL)) - FAIL_EXIT1 ("mount failed: %m\n"); + { + /* Probably rejected by local security policy. */ + if (errno == EPERM || errno == EACCES) + FAIL_UNSUPPORTED ("mount failed (security policy?): %m\n"); + else + FAIL_EXIT1 ("mount failed: %m\n"); + } const int fd = xopen ("mpoint", O_RDONLY | O_PATH | O_DIRECTORY | O_NOFOLLOW, 0); @@ -194,10 +200,11 @@ do_test (void) pid_t pid = xfork (); if (pid == 0) { - if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0) - _exit (EXIT_UNSUPPORTED); - else - _exit (0); + if (unshare (CLONE_NEWUSER | CLONE_NEWNS) != 0 + || mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0) + _exit (EXIT_UNSUPPORTED); + else + _exit (0); } int status; xwaitpid (pid, &status, 0); diff --git a/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c index ef62fbe941..89233ac4a1 100644 --- a/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c +++ b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c @@ -72,7 +72,7 @@ do_test (void) /* This happens if we're trying to create a nested container, like if the build is running under podman, and we lack priviledges. */ - if (errno == EPERM) + if (errno == EPERM || errno == EACCES) _exit (EXIT_UNSUPPORTED); else _exit (EXIT_FAILURE); base-commit: 1ea051145612f199d8716ecdf78b084b00b5a727 -- 2.43.0