From 5d9614077de26a294348bc9c872cd08da21c468d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 May 2018 21:57:00 +0200 Subject: [PATCH] nspawn: split out merging of settings object Let's separate the loading of the settings object and the merging into our arg_xyz fields into two. This will become particularly useful when we eventually are able to load settings from OCI runtime files in addition to .nspawn files. --- src/nspawn/nspawn.c | 395 ++++++++++++++++++++++---------------------- 1 file changed, 202 insertions(+), 193 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 460f109656..7d0cc117ce 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3174,12 +3174,212 @@ static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pi return 0; } +static int merge_settings(Settings *settings, const char *path) { + int rl; + + assert(settings); + assert(path); + + /* Copy over bits from the settings, unless they have been explicitly masked by command line switches. Note + * that this steals the fields of the Settings* structure, and hence modifies it. */ + + if ((arg_settings_mask & SETTING_START_MODE) == 0 && + settings->start_mode >= 0) { + arg_start_mode = settings->start_mode; + strv_free_and_replace(arg_parameters, settings->parameters); + } + + if ((arg_settings_mask & SETTING_PIVOT_ROOT) == 0 && + settings->pivot_root_new) { + free_and_replace(arg_pivot_root_new, settings->pivot_root_new); + free_and_replace(arg_pivot_root_old, settings->pivot_root_old); + } + + if ((arg_settings_mask & SETTING_WORKING_DIRECTORY) == 0 && + settings->working_directory) + free_and_replace(arg_chdir, settings->working_directory); + + if ((arg_settings_mask & SETTING_ENVIRONMENT) == 0 && + settings->environment) + strv_free_and_replace(arg_setenv, settings->environment); + + if ((arg_settings_mask & SETTING_USER) == 0 && + settings->user) + free_and_replace(arg_user, settings->user); + + if ((arg_settings_mask & SETTING_CAPABILITY) == 0) { + uint64_t plus; + + plus = settings->capability; + if (settings_private_network(settings)) + plus |= (1ULL << 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 + arg_caps_retain |= plus; + + arg_caps_retain &= ~settings->drop_capability; + } + + if ((arg_settings_mask & SETTING_KILL_SIGNAL) == 0 && + settings->kill_signal > 0) + arg_kill_signal = settings->kill_signal; + + if ((arg_settings_mask & SETTING_PERSONALITY) == 0 && + settings->personality != PERSONALITY_INVALID) + arg_personality = settings->personality; + + if ((arg_settings_mask & SETTING_MACHINE_ID) == 0 && + !sd_id128_is_null(settings->machine_id)) { + + if (!arg_settings_trusted) + log_warning("Ignoring MachineID= setting, file %s is not trusted.", path); + else + arg_uuid = settings->machine_id; + } + + if ((arg_settings_mask & SETTING_READ_ONLY) == 0 && + settings->read_only >= 0) + arg_read_only = settings->read_only; + + if ((arg_settings_mask & SETTING_VOLATILE_MODE) == 0 && + settings->volatile_mode != _VOLATILE_MODE_INVALID) + arg_volatile_mode = settings->volatile_mode; + + if ((arg_settings_mask & SETTING_CUSTOM_MOUNTS) == 0 && + settings->n_custom_mounts > 0) { + + if (!arg_settings_trusted) + log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", path); + else { + custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts); + arg_custom_mounts = TAKE_PTR(settings->custom_mounts); + arg_n_custom_mounts = settings->n_custom_mounts; + settings->n_custom_mounts = 0; + } + } + + if ((arg_settings_mask & SETTING_NETWORK) == 0 && + (settings->private_network >= 0 || + settings->network_veth >= 0 || + settings->network_bridge || + settings->network_zone || + settings->network_interfaces || + settings->network_macvlan || + settings->network_ipvlan || + settings->network_veth_extra)) { + + if (!arg_settings_trusted) + log_warning("Ignoring network settings, file %s is not trusted.", path); + else { + arg_network_veth = settings_network_veth(settings); + arg_private_network = settings_private_network(settings); + + strv_free_and_replace(arg_network_interfaces, settings->network_interfaces); + strv_free_and_replace(arg_network_macvlan, settings->network_macvlan); + strv_free_and_replace(arg_network_ipvlan, settings->network_ipvlan); + strv_free_and_replace(arg_network_veth_extra, settings->network_veth_extra); + + free_and_replace(arg_network_bridge, settings->network_bridge); + free_and_replace(arg_network_zone, settings->network_zone); + } + } + + if ((arg_settings_mask & SETTING_EXPOSE_PORTS) == 0 && + settings->expose_ports) { + + if (!arg_settings_trusted) + log_warning("Ignoring Port= setting, file %s is not trusted.", path); + else { + expose_port_free_all(arg_expose_ports); + arg_expose_ports = TAKE_PTR(settings->expose_ports); + } + } + + if ((arg_settings_mask & SETTING_USERNS) == 0 && + settings->userns_mode != _USER_NAMESPACE_MODE_INVALID) { + + if (!arg_settings_trusted) + log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", path); + else { + arg_userns_mode = settings->userns_mode; + arg_uid_shift = settings->uid_shift; + arg_uid_range = settings->uid_range; + arg_userns_chown = settings->userns_chown; + } + } + + if ((arg_settings_mask & SETTING_NOTIFY_READY) == 0) + arg_notify_ready = settings->notify_ready; + + if ((arg_settings_mask & SETTING_SYSCALL_FILTER) == 0) { + + if (!arg_settings_trusted && !strv_isempty(arg_syscall_whitelist)) + log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", path); + else { + strv_free_and_replace(arg_syscall_whitelist, settings->syscall_whitelist); + strv_free_and_replace(arg_syscall_blacklist, settings->syscall_blacklist); + } + } + + for (rl = 0; rl < _RLIMIT_MAX; rl ++) { + if ((arg_settings_mask & (SETTING_RLIMIT_FIRST << rl))) + continue; + + if (!settings->rlimit[rl]) + continue; + + if (!arg_settings_trusted) { + log_warning("Ignoring Limit%s= setting, file '%s' is not trusted.", rlimit_to_string(rl), path); + continue; + } + + free_and_replace(arg_rlimit[rl], settings->rlimit[rl]); + } + + if ((arg_settings_mask & SETTING_HOSTNAME) == 0 && + settings->hostname) + free_and_replace(arg_hostname, settings->hostname); + + if ((arg_settings_mask & SETTING_NO_NEW_PRIVILEGES) == 0 && + settings->no_new_privileges >= 0) + arg_no_new_privileges = settings->no_new_privileges; + + if ((arg_settings_mask & SETTING_OOM_SCORE_ADJUST) == 0 && + settings->oom_score_adjust_set) { + + if (!arg_settings_trusted) + log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", path); + else { + arg_oom_score_adjust = settings->oom_score_adjust; + arg_oom_score_adjust_set = true; + } + } + + if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 && + settings->cpuset) { + + if (!arg_settings_trusted) + log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path); + else { + if (arg_cpuset) + CPU_FREE(arg_cpuset); + arg_cpuset = TAKE_PTR(settings->cpuset); + arg_cpuset_ncpus = settings->cpuset_ncpus; + } + } + + return 0; +} + static int load_settings(void) { _cleanup_(settings_freep) Settings *settings = NULL; _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; const char *fn, *i; - int r, rl; + int r; /* If all settings are masked, there's no point in looking for * the settings file */ @@ -3245,198 +3445,7 @@ static int load_settings(void) { if (r < 0) return r; - /* Copy over bits from the settings, unless they have been - * explicitly masked by command line switches. */ - - if ((arg_settings_mask & SETTING_START_MODE) == 0 && - settings->start_mode >= 0) { - arg_start_mode = settings->start_mode; - strv_free_and_replace(arg_parameters, settings->parameters); - } - - if ((arg_settings_mask & SETTING_PIVOT_ROOT) == 0 && - settings->pivot_root_new) { - free_and_replace(arg_pivot_root_new, settings->pivot_root_new); - free_and_replace(arg_pivot_root_old, settings->pivot_root_old); - } - - if ((arg_settings_mask & SETTING_WORKING_DIRECTORY) == 0 && - settings->working_directory) - free_and_replace(arg_chdir, settings->working_directory); - - if ((arg_settings_mask & SETTING_ENVIRONMENT) == 0 && - settings->environment) - strv_free_and_replace(arg_setenv, settings->environment); - - if ((arg_settings_mask & SETTING_USER) == 0 && - settings->user) - free_and_replace(arg_user, settings->user); - - if ((arg_settings_mask & SETTING_CAPABILITY) == 0) { - uint64_t plus; - - plus = settings->capability; - if (settings_private_network(settings)) - plus |= (1ULL << CAP_NET_ADMIN); - - if (!arg_settings_trusted && plus != 0) { - if (settings->capability != 0) - log_warning("Ignoring Capability= setting, file %s is not trusted.", p); - } else - arg_caps_retain |= plus; - - arg_caps_retain &= ~settings->drop_capability; - } - - if ((arg_settings_mask & SETTING_KILL_SIGNAL) == 0 && - settings->kill_signal > 0) - arg_kill_signal = settings->kill_signal; - - if ((arg_settings_mask & SETTING_PERSONALITY) == 0 && - settings->personality != PERSONALITY_INVALID) - arg_personality = settings->personality; - - if ((arg_settings_mask & SETTING_MACHINE_ID) == 0 && - !sd_id128_is_null(settings->machine_id)) { - - if (!arg_settings_trusted) - log_warning("Ignoring MachineID= setting, file %s is not trusted.", p); - else - arg_uuid = settings->machine_id; - } - - if ((arg_settings_mask & SETTING_READ_ONLY) == 0 && - settings->read_only >= 0) - arg_read_only = settings->read_only; - - if ((arg_settings_mask & SETTING_VOLATILE_MODE) == 0 && - settings->volatile_mode != _VOLATILE_MODE_INVALID) - arg_volatile_mode = settings->volatile_mode; - - if ((arg_settings_mask & SETTING_CUSTOM_MOUNTS) == 0 && - settings->n_custom_mounts > 0) { - - if (!arg_settings_trusted) - log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", p); - else { - custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts); - arg_custom_mounts = TAKE_PTR(settings->custom_mounts); - arg_n_custom_mounts = settings->n_custom_mounts; - settings->n_custom_mounts = 0; - } - } - - if ((arg_settings_mask & SETTING_NETWORK) == 0 && - (settings->private_network >= 0 || - settings->network_veth >= 0 || - settings->network_bridge || - settings->network_zone || - settings->network_interfaces || - settings->network_macvlan || - settings->network_ipvlan || - settings->network_veth_extra)) { - - if (!arg_settings_trusted) - log_warning("Ignoring network settings, file %s is not trusted.", p); - else { - arg_network_veth = settings_network_veth(settings); - arg_private_network = settings_private_network(settings); - - strv_free_and_replace(arg_network_interfaces, settings->network_interfaces); - strv_free_and_replace(arg_network_macvlan, settings->network_macvlan); - strv_free_and_replace(arg_network_ipvlan, settings->network_ipvlan); - strv_free_and_replace(arg_network_veth_extra, settings->network_veth_extra); - - free_and_replace(arg_network_bridge, settings->network_bridge); - free_and_replace(arg_network_zone, settings->network_zone); - } - } - - if ((arg_settings_mask & SETTING_EXPOSE_PORTS) == 0 && - settings->expose_ports) { - - if (!arg_settings_trusted) - log_warning("Ignoring Port= setting, file %s is not trusted.", p); - else { - expose_port_free_all(arg_expose_ports); - arg_expose_ports = TAKE_PTR(settings->expose_ports); - } - } - - if ((arg_settings_mask & SETTING_USERNS) == 0 && - settings->userns_mode != _USER_NAMESPACE_MODE_INVALID) { - - if (!arg_settings_trusted) - log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", p); - else { - arg_userns_mode = settings->userns_mode; - arg_uid_shift = settings->uid_shift; - arg_uid_range = settings->uid_range; - arg_userns_chown = settings->userns_chown; - } - } - - if ((arg_settings_mask & SETTING_NOTIFY_READY) == 0) - arg_notify_ready = settings->notify_ready; - - if ((arg_settings_mask & SETTING_SYSCALL_FILTER) == 0) { - - if (!arg_settings_trusted && !strv_isempty(arg_syscall_whitelist)) - log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", p); - else { - strv_free_and_replace(arg_syscall_whitelist, settings->syscall_whitelist); - strv_free_and_replace(arg_syscall_blacklist, settings->syscall_blacklist); - } - } - - for (rl = 0; rl < _RLIMIT_MAX; rl ++) { - if ((arg_settings_mask & (SETTING_RLIMIT_FIRST << rl))) - continue; - - if (!settings->rlimit[rl]) - continue; - - if (!arg_settings_trusted) { - log_warning("Ignoring Limit%s= setting, file '%s' is not trusted.", rlimit_to_string(rl), p); - continue; - } - - free_and_replace(arg_rlimit[rl], settings->rlimit[rl]); - } - - if ((arg_settings_mask & SETTING_HOSTNAME) == 0 && - settings->hostname) - free_and_replace(arg_hostname, settings->hostname); - - if ((arg_settings_mask & SETTING_NO_NEW_PRIVILEGES) == 0 && - settings->no_new_privileges >= 0) - arg_no_new_privileges = settings->no_new_privileges; - - if ((arg_settings_mask & SETTING_OOM_SCORE_ADJUST) == 0 && - settings->oom_score_adjust_set) { - - if (!arg_settings_trusted) - log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", p); - else { - arg_oom_score_adjust = settings->oom_score_adjust; - arg_oom_score_adjust_set = true; - } - } - - if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 && - settings->cpuset) { - - if (!arg_settings_trusted) - log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", p); - else { - if (arg_cpuset) - CPU_FREE(arg_cpuset); - arg_cpuset = TAKE_PTR(settings->cpuset); - arg_cpuset_ncpus = settings->cpuset_ncpus; - } - } - - return 0; + return merge_settings(settings, p); } static int run(int master,