From d4d99bc6e4d90da335c62c7a75a2a12e44b428a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 1 Aug 2019 12:48:41 +0200 Subject: basic/cgroup-util: let cgroup_unified_flush() return the detected hierarchy This avoid the use of the global variable. Also rename cgroup_unified_update() to cgroup_unified_cached() and cgroup_unified_flush() to cgroup_unified() to better reflect their new roles. --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2aec8041f0..91ec61402b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4720,7 +4720,7 @@ static int run(int argc, char *argv[]) { if (r < 0) goto finish; - r = cg_unified_flush(); + r = cg_unified(); if (r < 0) { log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m"); goto finish; -- cgit v1.2.3 From 55fced5a1983cbe03197d782acdd673c035ba0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 1 Aug 2019 13:10:49 +0200 Subject: util-lib: move yes_no() and friends to string-util.h --- src/nspawn/test-patch-uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/test-patch-uid.c b/src/nspawn/test-patch-uid.c index b50f0990d8..a6829629b4 100644 --- a/src/nspawn/test-patch-uid.c +++ b/src/nspawn/test-patch-uid.c @@ -5,8 +5,8 @@ #include "log.h" #include "nspawn-patch-uid.h" #include "user-util.h" +#include "string-util.h" #include "tests.h" -#include "util.h" int main(int argc, char *argv[]) { uid_t shift, range; -- cgit v1.2.3 From fdb3decaa7ca791906f87dafc9d641c4cee4ec26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 1 Aug 2019 13:14:45 +0200 Subject: util-lib: move some functions from basic/cgroup-util to shared/cgroup-setup This way less stuff needs to be in basic. Initially, I wanted to move all the parts of cgroup-utils.[ch] that depend on efivars.[ch] to shared, because efivars.[ch] is in shared/. Later on, I decide to split efivars.[ch], so the move done in this patch is not necessary anymore. Nevertheless, it is still valid on its own. If at some point we want to expose libbasic, it is better to to not have stuff that belong in libshared there. --- src/nspawn/nspawn-cgroup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c index 0462b46413..f5048d9473 100644 --- a/src/nspawn/nspawn-cgroup.c +++ b/src/nspawn/nspawn-cgroup.c @@ -3,6 +3,7 @@ #include #include "alloc-util.h" +#include "cgroup-setup.h" #include "fd-util.h" #include "fileio.h" #include "format-util.h" -- cgit v1.2.3 From 38288f0bb843bf4c0ad7aacea5c81254b2d7d00b Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Sat, 21 Sep 2019 16:01:14 +0200 Subject: tree-wide: various code-formatting improvements Reported/found by Coccinelle --- src/nspawn/nspawn-mount.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 140df4e16b..2f842754a4 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -703,8 +703,9 @@ static int parse_mount_bind_options(const char *options, unsigned long *mount_fl else if (streq(word, "norbind")) flags &= ~MS_REC; else { - log_error("Invalid bind mount option: %s", word); - return -EINVAL; + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Invalid bind mount option: %s", + word); } } -- cgit v1.2.3 From 75b0d8b89d6e86319e75eaead3f4b0d187a66729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 27 Sep 2019 14:51:53 +0200 Subject: nspawn: default to unified hierarchy if --as-pid2 is used See comment added in the patch. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1756143. --- src/nspawn/nspawn.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2aec8041f0..ff6983eb7a 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -433,8 +433,8 @@ static int detect_unified_cgroup_hierarchy_from_environment(void) { static int detect_unified_cgroup_hierarchy_from_image(const char *directory) { int r; - /* Let's inherit the mode to use from the host system, but let's take into consideration what systemd in the - * image actually supports. */ + /* Let's inherit the mode to use from the host system, but let's take into consideration what systemd + * in the image actually supports. */ r = cg_all_unified(); if (r < 0) return log_error_errno(r, "Failed to determine whether we are in all unified mode."); @@ -1440,6 +1440,25 @@ static int parse_argv(int argc, char *argv[]) { static int verify_arguments(void) { int r; + if (arg_start_mode == START_PID2 && arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_UNKNOWN) { + /* If we are running the stub init in the container, we don't need to look at what the init + * in the container supports, because we are not using it. Let's immediately pick the right + * setting based on the host system configuration. + * + * We only do this, if the user didn't use an environment variable to override the detection. + */ + + r = cg_all_unified(); + if (r < 0) + return log_error_errno(r, "Failed to determine whether we are in all unified mode."); + if (r > 0) + arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL; + else if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) + arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_SYSTEMD; + else + arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE; + } + if (arg_userns_mode != USER_NAMESPACE_NO) arg_mount_settings |= MOUNT_USE_USERNS; -- cgit v1.2.3 From 490486842b6521104b594c511ca912504f61a8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 27 Sep 2019 13:58:06 +0200 Subject: nspawn: consistenly fail if parsing the environment fails We would parse the environment twice (to re-apply settings after reading config from disk), but we would not check the return code first time. This means that for some settings we would ignore invalid values, while for others, we'd fail at some point. Let's just consistently fail. Those environment variables define important aspects of behaviour, and it is better for the user if we ignore invalid values. (Unknown settings are still ignored, so forward compatibility is maintained.) --- src/nspawn/nspawn.c | 69 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ff6983eb7a..f16a19525b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -467,58 +467,66 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) { return 0; } -static void parse_share_ns_env(const char *name, unsigned long ns_flag) { +static int parse_share_ns_env(const char *name, unsigned long ns_flag) { int r; r = getenv_bool(name); if (r == -ENXIO) - return; + return 0; if (r < 0) - log_warning_errno(r, "Failed to parse %s from environment, defaulting to false.", name); + return log_error_errno(r, "Failed to parse $%s: %m", name); arg_clone_ns_flags = (arg_clone_ns_flags & ~ns_flag) | (r > 0 ? 0 : ns_flag); arg_settings_mask |= SETTING_CLONE_NS_FLAGS; + return 0; } -static void parse_mount_settings_env(void) { +static int parse_mount_settings_env(void) { const char *e; int r; r = getenv_bool("SYSTEMD_NSPAWN_TMPFS_TMP"); + if (r < 0 && r != -ENXIO) + return log_error_errno(r, "Failed to parse $SYSTEMD_NSPAWN_TMPFS_TMP: %m"); if (r >= 0) SET_FLAG(arg_mount_settings, MOUNT_APPLY_TMPFS_TMP, r > 0); - else if (r != -ENXIO) - log_warning_errno(r, "Failed to parse $SYSTEMD_NSPAWN_TMPFS_TMP, ignoring: %m"); e = getenv("SYSTEMD_NSPAWN_API_VFS_WRITABLE"); - if (!e) - return; - - if (streq(e, "network")) { + if (streq_ptr(e, "network")) arg_mount_settings |= MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS; - return; - } - r = parse_boolean(e); - if (r < 0) { - log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring."); - return; + else if (e) { + r = parse_boolean(e); + if (r < 0) + return log_error_errno(r, "Failed to parse $SYSTEMD_NSPAWN_API_VFS_WRITABLE: %m"); + + SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_RO, r == 0); + SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_NETNS, false); } - SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_RO, r == 0); - SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_NETNS, false); + return 0; } -static void parse_environment(void) { +static int parse_environment(void) { const char *e; int r; - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_IPC", CLONE_NEWIPC); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_PID", CLONE_NEWPID); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS); - parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS); + r = parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_IPC", CLONE_NEWIPC); + if (r < 0) + return r; + r = parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_PID", CLONE_NEWPID); + if (r < 0) + return r; + r = parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_NS_UTS", CLONE_NEWUTS); + if (r < 0) + return r; + r = parse_share_ns_env("SYSTEMD_NSPAWN_SHARE_SYSTEM", CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS); + if (r < 0) + return r; - parse_mount_settings_env(); + r = parse_mount_settings_env(); + if (r < 0) + return r; /* SYSTEMD_NSPAWN_USE_CGNS=0 can be used to disable CLONE_NEWCGROUP use, * even if it is supported. If not supported, it has no effect. */ @@ -528,7 +536,7 @@ static void parse_environment(void) { r = getenv_bool("SYSTEMD_NSPAWN_USE_CGNS"); if (r < 0) { if (r != -ENXIO) - log_warning_errno(r, "Failed to parse $SYSTEMD_NSPAWN_USE_CGNS, ignoring: %m"); + return log_error_errno(r, "Failed to parse $SYSTEMD_NSPAWN_USE_CGNS: %m"); arg_use_cgns = true; } else { @@ -541,7 +549,7 @@ static void parse_environment(void) { if (e) arg_container_service_name = e; - detect_unified_cgroup_hierarchy_from_environment(); + return detect_unified_cgroup_hierarchy_from_environment(); } static int parse_argv(int argc, char *argv[]) { @@ -1424,7 +1432,9 @@ static int parse_argv(int argc, char *argv[]) { arg_caps_retain = (arg_caps_retain | plus | (arg_private_network ? UINT64_C(1) << CAP_NET_ADMIN : 0)) & ~minus; /* Make sure to parse environment before we reset the settings mask below */ - parse_environment(); + r = parse_environment(); + if (r < 0) + return r; /* Load all settings from .nspawn files */ if (mask_no_settings) @@ -4749,9 +4759,8 @@ static int run(int argc, char *argv[]) { if (r < 0) goto finish; - r = detect_unified_cgroup_hierarchy_from_environment(); - if (r < 0) - goto finish; + /* Reapply environment settings. */ + (void) detect_unified_cgroup_hierarchy_from_environment(); /* Ignore SIGPIPE here, because we use splice() on the ptyfwd stuff and that will generate SIGPIPE if * the result is closed. Note that the container payload child will reset signal mask+handler anyway, -- cgit v1.2.3 From c78c095b1e6c87f309bbae5166f94d1bedc4ce81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 27 Sep 2019 14:17:41 +0200 Subject: nspawn: rename UNIFIED_CGROUP_HIERARCHY to SYSTEMD_NSPAWN_UNIFIED_HIERARCHY We should never have used an unprefixed environment variable name. All other systemd-nspawn variables have the "SYSTEMD_NSPAWN_" prefix, and all other systemd variables have the "SYSTEMD_" prefix. The new variable name takes precedence, but we fall back to checking the old one. If only the old one is found, a warning is emitted. In addition, SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="" is accepted as an override to avoid looking for the old variable name. We have a variable with the same name ($UNIFIED_CGROUP_HIERARCHY) in tests, which governs both systemd-nspawn and qemu behaviour. It is not renamed. --- src/nspawn/nspawn.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f16a19525b..0737517ddc 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -412,15 +412,27 @@ static int custom_mount_check_all(void) { } static int detect_unified_cgroup_hierarchy_from_environment(void) { - const char *e; + const char *e, *var = "SYSTEMD_NSPAWN_UNIFIED_HIERARCHY"; int r; /* Allow the user to control whether the unified hierarchy is used */ - e = getenv("UNIFIED_CGROUP_HIERARCHY"); - if (e) { + + e = getenv(var); + if (!e) { + static bool warned = false; + + var = "UNIFIED_CGROUP_HIERARCHY"; + e = getenv(var); + if (e && !warned) { + log_info("$UNIFIED_CGROUP_HIERARCHY has been renamed to $SYSTEMD_NSPAWN_UNIFIED_HIERARCHY."); + warned = true; + } + } + + if (!isempty(e)) { r = parse_boolean(e); if (r < 0) - return log_error_errno(r, "Failed to parse $UNIFIED_CGROUP_HIERARCHY."); + return log_error_errno(r, "Failed to parse $%s: %m", var); if (r > 0) arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL; else -- cgit v1.2.3 From de1b29f375b13b0566814517bf81e3cdbdd9a610 Mon Sep 17 00:00:00 2001 From: Nicolas Douma Date: Tue, 17 Sep 2019 05:07:00 +0200 Subject: nspawn: surrender controlling terminal to PID2 when using the PID1 stub --- src/nspawn/nspawn-stub-pid1.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c index ebf4f0f523..0589685afe 100644 --- a/src/nspawn/nspawn-stub-pid1.c +++ b/src/nspawn/nspawn-stub-pid1.c @@ -53,6 +53,12 @@ int stub_pid1(sd_id128_t uuid) { assert_se(sigfillset(&fullmask) >= 0); assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0); + /* Surrender the terminal this stub may control so that child processes can have a controlling terminal + * without resorting to setsid hacks. */ + r = ioctl(STDIN_FILENO, TIOCNOTTY); + if (r < 0 && errno != ENOTTY) + return log_error_errno(errno, "Failed to surrender controlling terminal: %m"); + pid = fork(); if (pid < 0) return log_error_errno(errno, "Failed to fork child pid: %m"); -- cgit v1.2.3 From dce66ffedbd4e72c2a1a35a55dc26c0e1029e8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 23 Oct 2019 09:20:46 +0200 Subject: nspawn: fix handling of --console=help We shouldn't continue to run the container after printing help. --- src/nspawn/nspawn.c | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0cd960157c..40a7de981a 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -261,6 +261,30 @@ STATIC_DESTRUCTOR_REGISTER(arg_seccomp, seccomp_releasep); STATIC_DESTRUCTOR_REGISTER(arg_cpu_set, cpu_set_reset); STATIC_DESTRUCTOR_REGISTER(arg_sysctl, strv_freep); +static int handle_arg_console(const char *arg) { + if (streq(arg, "help")) { + puts("interactive\n" + "read-only\n" + "passive\n" + "pipe"); + return 0; + } + + if (streq(arg, "interactive")) + arg_console_mode = CONSOLE_INTERACTIVE; + else if (streq(arg, "read-only")) + arg_console_mode = CONSOLE_READ_ONLY; + else if (streq(arg, "passive")) + arg_console_mode = CONSOLE_PASSIVE; + else if (streq(arg, "pipe")) + arg_console_mode = CONSOLE_PIPE; + else + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown console mode: %s", optarg); + + arg_settings_mask |= SETTING_CONSOLE_MODE; + return 1; +} + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -1389,29 +1413,16 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_CONSOLE: - if (streq(optarg, "interactive")) - arg_console_mode = CONSOLE_INTERACTIVE; - else if (streq(optarg, "read-only")) - arg_console_mode = CONSOLE_READ_ONLY; - else if (streq(optarg, "passive")) - arg_console_mode = CONSOLE_PASSIVE; - else if (streq(optarg, "pipe")) - arg_console_mode = CONSOLE_PIPE; - else if (streq(optarg, "help")) - puts("interactive\n" - "read-only\n" - "passive\n" - "pipe"); - else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown console mode: %s", optarg); - - arg_settings_mask |= SETTING_CONSOLE_MODE; + r = handle_arg_console(optarg); + if (r <= 0) + return r; break; case 'P': case ARG_PIPE: - arg_console_mode = CONSOLE_PIPE; - arg_settings_mask |= SETTING_CONSOLE_MODE; + r = handle_arg_console("pipe"); + if (r <= 0) + return r; break; case ARG_NO_PAGER: -- cgit v1.2.3 From a5648b809457d120500b2acb18b31e2168a4817a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 24 Oct 2019 10:33:20 +0200 Subject: basic/fs-util: change CHASE_OPEN flag into a separate output parameter chase_symlinks() would return negative on error, and either a non-negative status or a non-negative fd when CHASE_OPEN was given. This made the interface quite complicated, because dependning on the flags used, we would get two different "types" of return object. Coverity was always confused by this, and flagged every use of chase_symlinks() without CHASE_OPEN as a resource leak (because it would this that an fd is returned). This patch uses a saparate output parameter, so there is no confusion. (I think it is OK to have functions which return either an error or an fd. It's only returning *either* an fd or a non-fd that is confusing.) --- src/nspawn/nspawn-mount.c | 12 ++++++------ src/nspawn/nspawn.c | 15 +++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 2f842754a4..6407503c4c 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -633,7 +633,7 @@ int mount_all(const char *dest, if (!tmpfs_tmp && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_TMPFS_TMP)) continue; - r = chase_symlinks(mount_table[k].where, dest, CHASE_NONEXISTENT|CHASE_PREFIX_ROOT, &where); + r = chase_symlinks(mount_table[k].where, dest, CHASE_NONEXISTENT|CHASE_PREFIX_ROOT, &where, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where); @@ -734,7 +734,7 @@ static int mount_bind(const char *dest, CustomMount *m) { if (stat(m->source, &source_st) < 0) return log_error_errno(errno, "Failed to stat %s: %m", m->source); - r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where); + r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination); if (r > 0) { /* Path exists already? */ @@ -795,7 +795,7 @@ static int mount_tmpfs( assert(dest); assert(m); - r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where); + r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination); if (r == 0) { /* Doesn't exist yet? */ @@ -835,7 +835,7 @@ static int mount_overlay(const char *dest, CustomMount *m) { assert(dest); assert(m); - r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where); + r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination); if (r == 0) { /* Doesn't exist yet? */ @@ -878,7 +878,7 @@ static int mount_inaccessible(const char *dest, CustomMount *m) { assert(dest); assert(m); - r = chase_symlinks_and_stat(m->destination, dest, CHASE_PREFIX_ROOT, &where, &st); + r = chase_symlinks_and_stat(m->destination, dest, CHASE_PREFIX_ROOT, &where, &st, NULL); if (r < 0) { log_full_errno(m->graceful ? LOG_DEBUG : LOG_ERR, r, "Failed to resolve %s/%s: %m", dest, m->destination); return m->graceful ? 0 : r; @@ -906,7 +906,7 @@ static int mount_arbitrary(const char *dest, CustomMount *m) { assert(dest); assert(m); - r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where); + r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination); if (r == 0) { /* Doesn't exist yet? */ diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 40a7de981a..7760bcaa2d 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1668,7 +1668,7 @@ static int setup_timezone(const char *dest) { if (m == TIMEZONE_OFF) return 0; - r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc); + r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc, NULL); if (r < 0) { log_warning_errno(r, "Failed to resolve /etc path in container, ignoring: %m"); return 0; @@ -1699,7 +1699,7 @@ static int setup_timezone(const char *dest) { return 0; /* Already pointing to the right place? Then do nothing .. */ check = strjoina(dest, "/usr/share/zoneinfo/", z); - r = chase_symlinks(check, dest, 0, NULL); + r = chase_symlinks(check, dest, 0, NULL, NULL); if (r < 0) log_debug_errno(r, "Timezone %s does not exist (or is not accessible) in container, not creating symlink: %m", z); else { @@ -1726,7 +1726,7 @@ static int setup_timezone(const char *dest) { _cleanup_free_ char *resolved = NULL; int found; - found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved); + found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved, NULL); if (found < 0) { log_warning_errno(found, "Failed to resolve /etc/localtime path in container, ignoring: %m"); return 0; @@ -1832,7 +1832,7 @@ static int setup_resolv_conf(const char *dest) { if (m == RESOLV_CONF_OFF) return 0; - r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc); + r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc, NULL); if (r < 0) { log_warning_errno(r, "Failed to resolve /etc path in container, ignoring: %m"); return 0; @@ -1856,7 +1856,7 @@ static int setup_resolv_conf(const char *dest) { _cleanup_free_ char *resolved = NULL; int found; - found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved); + found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved, NULL); if (found < 0) { log_warning_errno(found, "Failed to resolve /etc/resolv.conf path in container, ignoring: %m"); return 0; @@ -2733,12 +2733,11 @@ static int chase_symlinks_and_update(char **p, unsigned flags) { if (!*p) return 0; - r = chase_symlinks(*p, NULL, flags, &chased); + r = chase_symlinks(*p, NULL, flags, &chased, NULL); if (r < 0) return log_error_errno(r, "Failed to resolve path %s: %m", *p); - free_and_replace(*p, chased); - return r; /* r might be an fd here in case we ever use CHASE_OPEN in flags */ + return free_and_replace(*p, chased); } static int determine_uid_shift(const char *directory) { -- cgit v1.2.3 From df7c4eb62a22a5b131007d98ee49f57f6f95483e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 24 Oct 2019 14:09:11 +0200 Subject: various tools: be more explicit when a glob is passed when not supported See https://bugzilla.redhat.com/show_bug.cgi?id=1763488: when we say that 'foo@*.service' is not a valid unit name, this is not clear enough. Let's include the name of the operation that does not support globbing in the error message: $ build/systemctl enable 'foo@*.service' Glob pattern passed to enable, but globs are not supported for this. Invalid unit name "foo@*.service" escaped as "foo@\x2a.service". ... --- src/nspawn/nspawn-register.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c index 8e2c329665..b2d931a8d3 100644 --- a/src/nspawn/nspawn-register.c +++ b/src/nspawn/nspawn-register.c @@ -258,7 +258,7 @@ int allocate_scope( if (r < 0) return log_error_errno(r, "Could not watch job: %m"); - r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope); + r = unit_name_mangle_with_suffix(machine_name, "as machine name", 0, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); @@ -350,7 +350,7 @@ int terminate_scope( _cleanup_free_ char *scope = NULL; int r; - r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope); + r = unit_name_mangle_with_suffix(machine_name, "to terminate", 0, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); -- cgit v1.2.3 From 0bb0a9faa7a9be917255648dcbc4b13132d90161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 29 Oct 2019 09:47:57 +0100 Subject: nspawn: when stopping the machine, just deregister the machine We already shut the machine down ourselves (and pid1 will also do cleanup for us after we exit if anything was left behind). No need for systemd-machined to try to stop the unit too. (This calls the new machined method. If we are running against an older machined, we will not deregister the machine. If we are simply exiting, machined should notice that the unit is gone on its own. If we are restarting, we will fail to register the machine after restart and fail. But this case was already broken, because machined would create a stop job, breaking the restart. So not doing anything with old machined should not make anything more broken than it already is.) Fixes #13766. --- src/nspawn/nspawn-register.c | 6 +++--- src/nspawn/nspawn-register.h | 2 +- src/nspawn/nspawn.c | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c index 8e2c329665..7541c56d8f 100644 --- a/src/nspawn/nspawn-register.c +++ b/src/nspawn/nspawn-register.c @@ -209,7 +209,7 @@ int register_machine( return 0; } -int terminate_machine( +int unregister_machine( sd_bus *bus, const char *machine_name) { @@ -223,13 +223,13 @@ int terminate_machine( "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", - "TerminateMachine", + "UnregisterMachine", &error, NULL, "s", machine_name); if (r < 0) - log_debug("Failed to terminate machine: %s", bus_error_message(&error, r)); + log_debug("Failed to unregister machine: %s", bus_error_message(&error, r)); return 0; } diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h index 65a3ae85a7..07cca7fadc 100644 --- a/src/nspawn/nspawn-register.h +++ b/src/nspawn/nspawn-register.h @@ -8,7 +8,7 @@ #include "nspawn-mount.h" int register_machine(sd_bus *bus, const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, sd_bus_message *properties_message, bool keep_unit, const char *service); -int terminate_machine(sd_bus *bus, const char *machine_name); +int unregister_machine(sd_bus *bus, const char *machine_name); int allocate_scope(sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, sd_bus_message *properties_message); int terminate_scope(sd_bus *bus, const char *machine_name); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index fed5c651ce..48244f3ae8 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4551,12 +4551,8 @@ static int run_container( } /* Kill if it is not dead yet anyway */ - if (bus) { - if (arg_register) - terminate_machine(bus, arg_machine); - else if (!arg_keep_unit) - terminate_scope(bus, arg_machine); - } + if (!arg_register && !arg_keep_unit && bus) + terminate_scope(bus, arg_machine); /* Normally redundant, but better safe than sorry */ (void) kill(*pid, SIGKILL); @@ -4564,6 +4560,10 @@ static int run_container( r = wait_for_container(*pid, &container_status); *pid = 0; + /* Tell machined that we are gone. */ + if (bus) + (void) unregister_machine(bus, arg_machine); + if (r < 0) /* We failed to wait for the container, or the container exited abnormally. */ return r; -- cgit v1.2.3 From f5947a5e925117c55b390460d592f57504277bf9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Oct 2019 11:07:23 +0900 Subject: tree-wide: drop missing.h --- src/nspawn/nspawn-patch-uid.c | 2 +- src/nspawn/nspawn-stub-pid1.c | 2 +- src/nspawn/nspawn.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index 4885744cfc..199e5804dd 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -14,7 +14,7 @@ #include "dirent-util.h" #include "fd-util.h" #include "fs-util.h" -#include "missing.h" +#include "missing_magic.h" #include "nspawn-def.h" #include "nspawn-patch-uid.h" #include "stat-util.h" diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c index 0589685afe..d86dd23185 100644 --- a/src/nspawn/nspawn-stub-pid1.c +++ b/src/nspawn/nspawn-stub-pid1.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +#include #include #include #include @@ -9,7 +10,6 @@ #include "exit-status.h" #include "fd-util.h" #include "log.h" -#include "missing.h" #include "nspawn-stub-pid1.h" #include "process-util.h" #include "signal-util.h" diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2ab308a958..c9ff00544c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -58,7 +58,7 @@ #include "machine-image.h" #include "macro.h" #include "main-func.h" -#include "missing.h" +#include "missing_sched.h" #include "mkdir.h" #include "mount-util.h" #include "mountpoint-util.h" -- cgit v1.2.3 From 43c3fb4680c8a2f8f417a71d7fbedde2db30f0c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Nov 2019 11:21:05 +0100 Subject: nspawn: mangle slice name It's user-facing, parsed from the command line and we typically mangle in these cases, let's do so here too. (In particular as the identical switch for systemd-run already does it.) --- src/nspawn/nspawn.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c9ff00544c..070a10fbeb 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -103,6 +103,7 @@ #include "terminal-util.h" #include "tmpfile-util.h" #include "umask-util.h" +#include "unit-name.h" #include "user-util.h" #include "util.h" @@ -891,13 +892,17 @@ static int parse_argv(int argc, char *argv[]) { arg_settings_mask |= SETTING_MACHINE_ID; break; - case 'S': - r = free_and_strdup(&arg_slice, optarg); + case 'S': { + _cleanup_free_ char *mangled = NULL; + + r = unit_name_mangle_with_suffix(optarg, NULL, UNIT_NAME_MANGLE_WARN, ".slice", &mangled); if (r < 0) return log_oom(); + free_and_replace(arg_slice, mangled); arg_settings_mask |= SETTING_SLICE; break; + } case 'M': if (isempty(optarg)) -- cgit v1.2.3 From 0ccdaa79ca69a40e4ad8b3e63b1236734751452e Mon Sep 17 00:00:00 2001 From: Justin Trudell Date: Fri, 1 Nov 2019 12:00:16 -0700 Subject: nspawn: respect quiet on capabilities warning --- src/nspawn/nspawn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 070a10fbeb..3513c015b8 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2390,7 +2390,8 @@ static int drop_capabilities(uid_t uid) { /* If we're not using OCI, proceed with mangled capabilities (so we don't error out) * in order to maintain the same behavior as systemd < 242. */ if (capability_quintet_mangle(&q)) - log_warning("Some capabilities will not be set because they are not in the current bounding set."); + log_full(arg_quiet ? LOG_DEBUG : LOG_WARNING, + "Some capabilities will not be set because they are not in the current bounding set."); } -- cgit v1.2.3 From 455fa9610cba06af4cb9d8c8a2121b552c4d2229 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 17:44:54 +0900 Subject: tree-wide: drop string.h when string-util.h or friends are included --- src/nspawn/nspawn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 3513c015b8..dfd14ca390 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From df26692947ac556a20ce0a6f1585db18871ace1c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:16:18 +0900 Subject: tree-wide: drop sched.h when missing_sched.h is included --- src/nspawn/nspawn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index dfd14ca390..db3bc1a4db 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -9,7 +9,6 @@ #include #include #include -#include #if HAVE_SELINUX #include #endif -- cgit v1.2.3 From 927d2351d73d977940852379a3869b96539e37bf Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:18:31 +0900 Subject: tree-wide: drop pwd.h and grp.h when user-util.h is included --- src/nspawn/nspawn-setuid.c | 1 - src/nspawn/nspawn.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 3c302d6487..cb2b2272b6 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include -#include #include #include diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index db3bc1a4db..3a866980c8 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5,10 +5,8 @@ #endif #include #include -#include #include #include -#include #if HAVE_SELINUX #include #endif -- cgit v1.2.3 From e25910849441372339340bc8ce1ce990e126ac63 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:19:54 +0900 Subject: tree-wide: drop acl.h when acl-util.h is included --- src/nspawn/nspawn-patch-uid.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index 199e5804dd..c2f068fa99 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -2,9 +2,6 @@ #include #include -#if HAVE_ACL -#include -#endif #include #include #include -- cgit v1.2.3 From adb29d588ed8497d2c51f1d6d5e45a1e0d80a1dd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:20:31 +0900 Subject: tree-wide: drop blkid.h when blkid-util.h is included --- src/nspawn/nspawn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 3a866980c8..6439e604da 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #if HAVE_BLKID -#include #endif #include #include -- cgit v1.2.3 From e30e8b50738daab74eee56027543dea4d8ff8a32 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:23:26 +0900 Subject: tree-wide: drop stat.h or statfs.h when stat-util.h is included --- src/nspawn/nspawn-patch-uid.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index c2f068fa99..7c1dbc2cf4 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -2,7 +2,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From 0fb81b8abe8d87f0b9a55f75c19438e55b5f7395 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:24:45 +0900 Subject: tree-wide: drop magic.h when missing_magic.h is included --- src/nspawn/nspawn-patch-uid.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index 7c1dbc2cf4..fc591e2725 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include -#include #include #include #include -- cgit v1.2.3 From 021cdf8330b29256e19a34fb4eecf95e9fa9a81b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:27:01 +0900 Subject: tree-wide: drop signal.h when signal-util.h is included --- src/nspawn/nspawn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 6439e604da..eafc52a4b2 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -9,7 +9,6 @@ #if HAVE_SELINUX #include #endif -#include #include #include #include -- cgit v1.2.3 From 1405cb653ae8588404e64af0265bb0bec47537b4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 1 Nov 2019 18:27:33 +0900 Subject: tree-wide: drop stdio.h when stdio-util.h is included --- src/nspawn/nspawn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index eafc52a4b2..c87e859194 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -9,7 +9,6 @@ #if HAVE_SELINUX #include #endif -#include #include #include #include -- cgit v1.2.3 From 9493b168717a445abb12f62c2503edd019e00ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 8 Nov 2019 12:56:56 +0100 Subject: Add @pkey syscall group Inspired by https://bugzilla.redhat.com/show_bug.cgi?id=1769299. This change doesn't solve the issue, but makes it easier to whitelist the syscall group. --- src/nspawn/nspawn-seccomp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c index 9222f2bc84..0b39cda9ba 100644 --- a/src/nspawn/nspawn-seccomp.c +++ b/src/nspawn/nspawn-seccomp.c @@ -123,6 +123,7 @@ static int seccomp_add_default_syscall_filter( * @cpu-emulation * @keyring (NB: keyring is not namespaced!) * @obsolete + * @pkey * @swap * * bpf (NB: bpffs is not namespaced!) @@ -134,9 +135,6 @@ static int seccomp_add_default_syscall_filter( * nfsservctl * open_by_handle_at * perf_event_open - * pkey_alloc - * pkey_free - * pkey_mprotect * quotactl */ }; -- cgit v1.2.3 From d5fc5b2f8d62ba2a79eb755272e67ff3f117c5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 12 Nov 2019 21:10:48 +0100 Subject: nspawn: do not emit any warning when $UNIFIED_CGROUP_HIERARCHY is used Initially I thought this is a good idea, but when reviewing a different PR (https://github.com/systemd/systemd/pull/13862#discussion_r340604313) I changed my mind about this. At some point we probably should start warning about the old option name, and yet later remove it. But it'll make it easier for people to transition to the new option name if there's a period of support for both names without any fuss. There's nothing particularly wrong about the old name, and there is no support cost. Fixes #13919 (by avoiding the issue completely). --- src/nspawn/nspawn.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c87e859194..ea781e2b38 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -437,14 +437,9 @@ static int detect_unified_cgroup_hierarchy_from_environment(void) { e = getenv(var); if (!e) { - static bool warned = false; - + /* $UNIFIED_CGROUP_HIERARCHY has been renamed to $SYSTEMD_NSPAWN_UNIFIED_HIERARCHY. */ var = "UNIFIED_CGROUP_HIERARCHY"; e = getenv(var); - if (e && !warned) { - log_info("$UNIFIED_CGROUP_HIERARCHY has been renamed to $SYSTEMD_NSPAWN_UNIFIED_HIERARCHY."); - warned = true; - } } if (!isempty(e)) { -- cgit v1.2.3 From 7be830c6e8cd3852e3468203812445115f5ea183 Mon Sep 17 00:00:00 2001 From: Torsten Hilbrich Date: Tue, 12 Nov 2019 08:36:06 +0100 Subject: nspawn: Allow Capability= to overrule private network setting The commit: a3fc6b55ac nspawn: mask out CAP_NET_ADMIN again if settings file turns off private networking turned off the CAP_NET_ADMIN capability whenever no private networking feature was enabled. This broke configurations where the CAP_NET_ADMIN capability was explicitly requested in the configuration. Changing the order of evalution here to allow the Capability= setting to overrule this implicit setting: Order of evaluation: 1. if no private network setting is enabled, CAP_NET_ADMIN is removed 2. if a private network setting is enabled, CAP_NET_ADMIN is added 3. the settings of Capability= are added 4. the settings of DropCapability= are removed This allows the fix for #11755 to be retained and to still allow the admin to specify CAP_NET_ADMIN as additional capability. Fixes: a3fc6b55acd3f37e50915304d87bed100efa9d9d Fixes: #13995 --- src/nspawn/nspawn.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ea781e2b38..6286a28f1d 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3770,6 +3770,7 @@ static int merge_settings(Settings *settings, const char *path) { if ((arg_settings_mask & SETTING_CAPABILITY) == 0) { uint64_t plus, minus; + uint64_t network_minus = 0; /* Note that we copy both the simple plus/minus caps here, and the full quintet from the * Settings structure */ @@ -3781,14 +3782,16 @@ static int merge_settings(Settings *settings, const char *path) { if (settings_private_network(settings)) plus |= UINT64_C(1) << CAP_NET_ADMIN; else - minus |= UINT64_C(1) << CAP_NET_ADMIN; + network_minus |= UINT64_C(1) << CAP_NET_ADMIN; } if (!arg_settings_trusted && plus != 0) { if (settings->capability != 0) log_warning("Ignoring Capability= setting, file %s is not trusted.", path); - } else + } else { + arg_caps_retain &= ~network_minus; arg_caps_retain |= plus; + } arg_caps_retain &= ~minus; -- cgit v1.2.3 From 8a99bd0c4601f639678b80db90db45609c90c5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 20 Nov 2019 18:33:32 +0100 Subject: nspawn: dump capability list with --capabilities=help --- src/nspawn/nspawn.c | 76 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 28 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 6286a28f1d..7f44272a88 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -492,6 +492,46 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) { return 0; } +static int parse_capability_spec(const char *spec, uint64_t *ret_mask) { + uint64_t mask = 0; + int r; + + for (;;) { + _cleanup_free_ char *t = NULL; + + r = extract_first_word(&spec, &t, ",", 0); + if (r < 0) + return log_error_errno(r, "Failed to parse capability %s.", t); + if (r == 0) + break; + + if (streq(t, "help")) { + for (int i = 0; i < capability_list_length(); i++) { + const char *name; + + name = capability_to_name(i); + if (name) + puts(name); + } + + return 0; /* quit */ + } + + if (streq(t, "all")) + mask = (uint64_t) -1; + else { + r = capability_from_name(t); + if (r < 0) + return log_error_errno(r, "Failed to parse capability %s.", t); + + mask |= 1ULL << r; + } + } + + *ret_mask = mask; + return 1; /* continue */ +} + static int parse_share_ns_env(const char *name, unsigned long ns_flag) { int r; @@ -695,7 +735,6 @@ static int parse_argv(int argc, char *argv[]) { }; int c, r; - const char *p; uint64_t plus = 0, minus = 0; bool mask_all_settings = false, mask_no_settings = false; @@ -937,37 +976,18 @@ static int parse_argv(int argc, char *argv[]) { case ARG_CAPABILITY: case ARG_DROP_CAPABILITY: { - p = optarg; - for (;;) { - _cleanup_free_ char *t = NULL; - - r = extract_first_word(&p, &t, ",", 0); - if (r < 0) - return log_error_errno(r, "Failed to parse capability %s.", t); - if (r == 0) - break; - - if (streq(t, "all")) { - if (c == ARG_CAPABILITY) - plus = (uint64_t) -1; - else - minus = (uint64_t) -1; - } else { - r = capability_from_name(t); - if (r < 0) - return log_error_errno(r, "Failed to parse capability %s.", t); - - if (c == ARG_CAPABILITY) - plus |= 1ULL << r; - else - minus |= 1ULL << r; - } - } + uint64_t m; + r = parse_capability_spec(optarg, &m); + if (r <= 0) + return r; + if (c == ARG_CAPABILITY) + plus |= m; + else + minus |= m; arg_settings_mask |= SETTING_CAPABILITY; break; } - case ARG_NO_NEW_PRIVILEGES: r = parse_boolean(optarg); if (r < 0) -- cgit v1.2.3 From f47bd0974918abdb2f2453e8efec9be7409d9add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 20 Nov 2019 19:02:36 +0100 Subject: nspawn: log syscalls we cannot add at debug level Without out at least a debug log line it is hard to figure out when something goes wrong. Reduce scope of a variable while at it. --- src/nspawn/nspawn-seccomp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c index 0b39cda9ba..f94f131f22 100644 --- a/src/nspawn/nspawn-seccomp.c +++ b/src/nspawn/nspawn-seccomp.c @@ -139,11 +139,10 @@ static int seccomp_add_default_syscall_filter( */ }; - int r; - size_t i; char **p; + int r; - for (i = 0; i < ELEMENTSOF(whitelist); i++) { + for (size_t i = 0; i < ELEMENTSOF(whitelist); i++) { if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0) continue; @@ -153,7 +152,7 @@ static int seccomp_add_default_syscall_filter( } STRV_FOREACH(p, syscall_whitelist) { - r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false); + r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, true); if (r < 0) log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch)); -- cgit v1.2.3 From 37a92352d6bbac65ca6b1b3c958939a4ccc7d51a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Nov 2019 10:51:31 +0100 Subject: nspawn: highlight description string in --help text We do so in most tools now, do so here, too. --- src/nspawn/nspawn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 7f44272a88..873a76596f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -290,7 +290,7 @@ static int help(void) { return log_oom(); printf("%1$s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" - "Spawn a command or OS in a light-weight container.\n\n" + "%5$sSpawn a command or OS in a light-weight container.%6$s\n\n" " -h --help Show this help\n" " --version Print version string\n" " -q --quiet Do not show status information\n" @@ -405,7 +405,9 @@ static int help(void) { "\nSee the %2$s for details.\n" , program_invocation_short_name , link - , ansi_underline(), ansi_normal()); + , ansi_underline(), ansi_normal() + , ansi_highlight(), ansi_normal() + ); return 0; } -- cgit v1.2.3 From c152a2ba54dc77322997e8f5e302518fe4b07e57 Mon Sep 17 00:00:00 2001 From: afg Date: Fri, 29 Nov 2019 17:08:05 +0800 Subject: nspawn: allow Capability=all in systemd.nspawn [EXEC] section Just like --capability=all is allowed in the systemd-nspawn command line. --- src/nspawn/nspawn-settings.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c index 3a99736813..5fb5b49bbc 100644 --- a/src/nspawn/nspawn-settings.c +++ b/src/nspawn/nspawn-settings.c @@ -275,13 +275,17 @@ int config_parse_capability( if (r == 0) break; - r = capability_from_name(word); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse capability, ignoring: %s", word); - continue; - } + if (streq(word, "all")) + u = (uint64_t) -1; + else { + r = capability_from_name(word); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse capability, ignoring: %s", word); + continue; + } - u |= UINT64_C(1) << r; + u |= UINT64_C(1) << r; + } } if (u == 0) -- cgit v1.2.3