diff --git a/TODO b/TODO index 7437938bf0..837b825024 100644 --- a/TODO +++ b/TODO @@ -38,8 +38,6 @@ Features: * cache sd_event_now() result from before the first iteration... -* remove Capabilities=, after all AmbientCapabilities= and CapabilityBoundingSet= should be enough. - * support for the new copy_file_range() syscall * add systemctl stop --job-mode=triggering that follows TRIGGERED_BY deps and adds them to the same transaction diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml index 3bcda46656..4c05835568 100644 --- a/man/sd_bus_creds_get_pid.xml +++ b/man/sd_bus_creds_get_pid.xml @@ -406,15 +406,11 @@ For processes that are not part of a session, returns -ENXIO. - sd_bus_creds_has_effective_cap() will - check whether the capability specified by - capability was set in the effective - capabilities mask. A positive return value means that is was - set, zero means that it was not set, and a negative return - value indicates an error. See - capabilities7 - and Capabilities= and - CapabilityBoundingSet= settings in + sd_bus_creds_has_effective_cap() will check whether the capability specified by + capability was set in the effective capabilities mask. A positive return value means that it + was set, zero means that it was not set, and a negative return value indicates an error. See capabilities7 and the + AmbientCapabilities= and CapabilityBoundingSet= settings in systemd.exec5. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index f0f77c5091..008565c14b 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -778,32 +778,21 @@ CapabilityBoundingSet= - Controls which capabilities to include in the - capability bounding set for the executed process. See - capabilities7 - for details. Takes a whitespace-separated list of capability - names as read by - cap_from_name3, - e.g. CAP_SYS_ADMIN, - CAP_DAC_OVERRIDE, - CAP_SYS_PTRACE. Capabilities listed will - be included in the bounding set, all others are removed. If - the list of capabilities is prefixed with - ~, all but the listed capabilities will be - included, the effect of the assignment inverted. Note that - this option also affects the respective capabilities in the - effective, permitted and inheritable capability sets, on top - of what Capabilities= does. If this option - is not used, the capability bounding set is not modified on - process execution, hence no limits on the capabilities of the - process are enforced. This option may appear more than once, in - which case the bounding sets are merged. If the empty string - is assigned to this option, the bounding set is reset to the - empty capability set, and all prior settings have no effect. - If set to ~ (without any further argument), - the bounding set is reset to the full set of available - capabilities, also undoing any previous - settings. + Controls which capabilities to include in the capability bounding set for the executed + process. See capabilities7 for + details. Takes a whitespace-separated list of capability names as read by cap_from_name3, + e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, + CAP_SYS_PTRACE. Capabilities listed will be included in the bounding set, all others are + removed. If the list of capabilities is prefixed with ~, all but the listed capabilities + will be included, the effect of the assignment inverted. Note that this option also affects the respective + capabilities in the effective, permitted and inheritable capability sets. If this option is not used, the + capability bounding set is not modified on process execution, hence no limits on the capabilities of the + process are enforced. This option may appear more than once, in which case the bounding sets are merged. If the + empty string is assigned to this option, the bounding set is reset to the empty capability set, and all prior + settings have no effect. If set to ~ (without any further argument), the bounding set is + reset to the full set of available capabilities, also undoing any previous settings. @@ -853,20 +842,6 @@ for details. - - Capabilities= - Controls the - capabilities7 - set for the executed process. Take a capability string - describing the effective, permitted and inherited capability - sets as documented in - cap_from_text3. - Note that these capability sets are usually influenced (and - filtered) by the capabilities attached to the executed file. - Due to that CapabilityBoundingSet= is - probably a much more useful setting. - - ReadWriteDirectories= ReadOnlyDirectories= diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index f2fc301f8e..973a60187d 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -312,7 +312,7 @@ static int property_get_ambient_capabilities( return sd_bus_message_append(reply, "t", c->capability_ambient_set); } -static int property_get_capabilities( +static int property_get_empty_string( sd_bus *bus, const char *path, const char *interface, @@ -321,23 +321,10 @@ static int property_get_capabilities( void *userdata, sd_bus_error *error) { - ExecContext *c = userdata; - _cleanup_cap_free_charp_ char *t = NULL; - const char *s; - assert(bus); assert(reply); - assert(c); - if (c->capabilities) - s = t = cap_to_text(c->capabilities, NULL); - else - s = ""; - - if (!s) - return -ENOMEM; - - return sd_bus_message_append(reply, "s", s); + return sd_bus_message_append(reply, "s", ""); } static int property_get_syscall_filter( @@ -700,7 +687,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index 30f7e05b90..184c72dbe7 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -746,10 +746,10 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_ static int enforce_user(const ExecContext *context, uid_t uid) { assert(context); - /* Sets (but doesn't lookup) the uid and make sure we keep the + /* Sets (but doesn't look up) the uid and make sure we keep the * capabilities while doing so. */ - if (context->capabilities || context->capability_ambient_set != 0) { + if (context->capability_ambient_set != 0) { /* First step: If we need to keep capabilities but * drop privileges we need to make sure we keep our @@ -761,31 +761,9 @@ static int enforce_user(const ExecContext *context, uid_t uid) { if (prctl(PR_SET_SECUREBITS, sb) < 0) return -errno; } - - /* Second step: set the capabilities. This will reduce - * the capabilities to the minimum we need. */ - - if (context->capabilities) { - _cleanup_cap_free_ cap_t d = NULL; - static const cap_value_t bits[] = { - CAP_SETUID, /* Necessary so that we can run setresuid() below */ - CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */ - }; - - d = cap_dup(context->capabilities); - if (!d) - return -errno; - - if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 || - cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) - return -errno; - - if (cap_set_proc(d) < 0) - return -errno; - } } - /* Third step: actually set the uids */ + /* Second step: actually set the uids */ if (setresuid(uid, uid, uid) < 0) return -errno; @@ -1874,21 +1852,6 @@ static int exec_child( *exit_status = EXIT_CAPABILITIES; return r; } - - if (context->capabilities) { - - /* The capabilities in ambient set need to be also in the inherited - * set. If they aren't, trying to get them will fail. Add the ambient - * set inherited capabilities to the capability set in the context. - * This is needed because if capabilities are set (using "Capabilities=" - * keyword), they will override whatever we set now. */ - - r = capability_update_inherited_set(context->capabilities, context->capability_ambient_set); - if (r < 0) { - *exit_status = EXIT_CAPABILITIES; - return r; - } - } } if (context->user) { @@ -1927,12 +1890,6 @@ static int exec_child( return -errno; } - if (context->capabilities) - if (cap_set_proc(context->capabilities) < 0) { - *exit_status = EXIT_CAPABILITIES; - return -errno; - } - if (context->no_new_privileges) if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { *exit_status = EXIT_NO_NEW_PRIVILEGES; @@ -2175,11 +2132,6 @@ void exec_context_done(ExecContext *c) { c->pam_name = mfree(c->pam_name); - if (c->capabilities) { - cap_free(c->capabilities); - c->capabilities = NULL; - } - c->read_only_dirs = strv_free(c->read_only_dirs); c->read_write_dirs = strv_free(c->read_write_dirs); c->inaccessible_dirs = strv_free(c->inaccessible_dirs); @@ -2538,14 +2490,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { prefix, strna(lvl_str)); } - if (c->capabilities) { - _cleanup_cap_free_charp_ char *t; - - t = cap_to_text(c->capabilities, NULL); - if (t) - fprintf(f, "%sCapabilities: %s\n", prefix, t); - } - if (c->secure_bits) fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n", prefix, diff --git a/src/core/execute.h b/src/core/execute.h index f7205701f4..41148bcea2 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -155,10 +155,7 @@ struct ExecContext { unsigned long mount_flags; uint64_t capability_bounding_set; - uint64_t capability_ambient_set; - - cap_t capabilities; int secure_bits; int syslog_priority; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index fde64c9747..5568b4696f 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -45,7 +45,7 @@ $1.SyslogIdentifier, config_parse_unit_string_printf, 0, $1.SyslogFacility, config_parse_log_facility, 0, offsetof($1, exec_context.syslog_priority) $1.SyslogLevel, config_parse_log_level, 0, offsetof($1, exec_context.syslog_priority) $1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix) -$1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context) +$1.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof($1, exec_context) $1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) $1.CapabilityBoundingSet, config_parse_capability_set, 0, offsetof($1, exec_context.capability_bounding_set) $1.AmbientCapabilities, config_parse_capability_set, 0, offsetof($1, exec_context.capability_ambient_set) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index ba551fb41d..b31bf83f47 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -951,38 +951,6 @@ int config_parse_exec_cpu_affinity(const char *unit, return 0; } -int config_parse_exec_capabilities(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - ExecContext *c = data; - cap_t cap; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - cap = cap_from_text(rvalue); - if (!cap) { - log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse capabilities, ignoring: %s", rvalue); - return 0; - } - - if (c->capabilities) - cap_free(c->capabilities); - c->capabilities = cap; - - return 0; -} - int config_parse_exec_secure_bits(const char *unit, const char *filename, unsigned line, @@ -3797,7 +3765,6 @@ void unit_dump_config_items(FILE *f) { { config_parse_input, "INPUT" }, { config_parse_log_facility, "FACILITY" }, { config_parse_log_level, "LEVEL" }, - { config_parse_exec_capabilities, "CAPABILITIES" }, { config_parse_exec_secure_bits, "SECUREBITS" }, { config_parse_capability_set, "BOUNDINGSET" }, { config_parse_limit, "LIMIT" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 372d05a61d..34f15afa62 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -52,7 +52,6 @@ int config_parse_exec_io_priority(const char *unit, const char *filename, unsign int config_parse_exec_cpu_sched_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_cpu_sched_prio(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_cpu_affinity(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_exec_capabilities(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_secure_bits(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_capability_set(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);