diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-05-24 04:00:56 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-05-24 04:00:56 +0200 |
commit | ec8927ca5940e809f0b72f530582c76f1db4f065 (patch) | |
tree | b230d2458088a82b879afc39a2752d5fc674974e /src/core | |
parent | e056b01d8acea7fc06d52ef91d227d744faf5259 (diff) |
main: add configuration option to alter capability bounding set for PID 1
This also ensures that caps dropped from the bounding set are also
dropped from the inheritable set, to be extra-secure. Usually that should
change very little though as the inheritable set is empty for all our uses
anyway.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/execute.c | 64 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 2 | ||||
-rw-r--r-- | src/core/load-fragment.c | 13 | ||||
-rw-r--r-- | src/core/load-fragment.h | 2 | ||||
-rw-r--r-- | src/core/main.c | 11 | ||||
-rw-r--r-- | src/core/system.conf | 17 |
6 files changed, 38 insertions, 71 deletions
diff --git a/src/core/execute.c b/src/core/execute.c index bb841b7fcf..9c2006ebc7 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -870,68 +870,6 @@ fail: } #endif -static int do_capability_bounding_set_drop(uint64_t drop) { - unsigned long i; - cap_t old_cap = NULL, new_cap = NULL; - cap_flag_value_t fv; - int r; - - /* If we are run as PID 1 we will lack CAP_SETPCAP by default - * in the effective set (yes, the kernel drops that when - * executing init!), so get it back temporarily so that we can - * call PR_CAPBSET_DROP. */ - - old_cap = cap_get_proc(); - if (!old_cap) - return -errno; - - if (cap_get_flag(old_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) { - r = -errno; - goto finish; - } - - if (fv != CAP_SET) { - static const cap_value_t v = CAP_SETPCAP; - - new_cap = cap_dup(old_cap); - if (!new_cap) { - r = -errno; - goto finish; - } - - if (cap_set_flag(new_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) { - r = -errno; - goto finish; - } - - if (cap_set_proc(new_cap) < 0) { - r = -errno; - goto finish; - } - } - - for (i = 0; i <= cap_last_cap(); i++) - if (drop & ((uint64_t) 1ULL << (uint64_t) i)) { - if (prctl(PR_CAPBSET_DROP, i) < 0) { - r = -errno; - goto finish; - } - } - - r = 0; - -finish: - if (new_cap) - cap_free(new_cap); - - if (old_cap) { - cap_set_proc(old_cap); - cap_free(old_cap); - } - - return r; -} - static void rename_process_from_path(const char *path) { char process_name[11]; const char *p; @@ -1398,7 +1336,7 @@ int exec_spawn(ExecCommand *command, } if (context->capability_bounding_set_drop) { - err = do_capability_bounding_set_drop(context->capability_bounding_set_drop); + err = capability_bounding_set_drop(context->capability_bounding_set_drop, false); if (err < 0) { r = EXIT_CAPABILITIES; goto fail_child; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index ea502bd288..6f2a0d63ef 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -46,7 +46,7 @@ $1.SyslogLevel, config_parse_level, 0, $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.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) -$1.CapabilityBoundingSet, config_parse_exec_bounding_set, 0, offsetof($1, exec_context) +$1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop) $1.TimerSlackNSec, config_parse_exec_timer_slack_nsec, 0, offsetof($1, exec_context) $1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) $1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index d2267722dd..ff6e13e599 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -931,7 +931,7 @@ int config_parse_exec_secure_bits( return 0; } -int config_parse_exec_bounding_set( +int config_parse_bounding_set( const char *filename, unsigned line, const char *section, @@ -941,7 +941,7 @@ int config_parse_exec_bounding_set( void *data, void *userdata) { - ExecContext *c = data; + uint64_t *capability_bounding_set_drop = data; char *w; size_t l; char *state; @@ -968,7 +968,8 @@ int config_parse_exec_bounding_set( int r; cap_value_t cap; - if (!(t = strndup(w, l))) + t = strndup(w, l); + if (!t) return -ENOMEM; r = cap_from_name(t, &cap); @@ -983,9 +984,9 @@ int config_parse_exec_bounding_set( } if (invert) - c->capability_bounding_set_drop |= sum; + *capability_bounding_set_drop |= sum; else - c->capability_bounding_set_drop |= ~sum; + *capability_bounding_set_drop |= ~sum; return 0; } @@ -2447,7 +2448,7 @@ void unit_dump_config_items(FILE *f) { { config_parse_level, "LEVEL" }, { config_parse_exec_capabilities, "CAPABILITIES" }, { config_parse_exec_secure_bits, "SECUREBITS" }, - { config_parse_exec_bounding_set, "BOUNDINGSET" }, + { config_parse_bounding_set, "BOUNDINGSET" }, { config_parse_exec_timer_slack_nsec, "TIMERSLACK" }, { config_parse_limit, "LIMIT" }, { config_parse_unit_cgroup, "CGROUP [...]" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 3b2ed096b5..6b382494aa 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -56,7 +56,7 @@ int config_parse_exec_cpu_sched_prio(const char *filename, unsigned line, const int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_exec_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_timer_slack_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/core/main.c b/src/core/main.c index 4d9a2d453e..9248c388a4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -50,6 +50,7 @@ #include "watchdog.h" #include "path-util.h" #include "switch-root.h" +#include "capability.h" #include "mount-setup.h" #include "loopback-setup.h" @@ -88,6 +89,7 @@ static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; static usec_t arg_runtime_watchdog = 0; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {}; +static uint64_t arg_capability_bounding_set_drop = 0; static FILE* serialization = NULL; @@ -678,6 +680,7 @@ static int parse_config_file(void) { { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog }, { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog }, + { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop }, { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]}, { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]}, { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]}, @@ -1484,6 +1487,14 @@ int main(int argc, char *argv[]) { if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0) watchdog_set_timeout(&arg_runtime_watchdog); + if (arg_capability_bounding_set_drop) { + r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + if (r < 0) { + log_error("Failed to drop capability bounding set: %s", strerror(-r)); + goto finish; + } + } + r = manager_new(arg_running_as, &m); if (r < 0) { log_error("Failed to allocate manager object: %s", strerror(-r)); diff --git a/src/core/system.conf b/src/core/system.conf index 2b14d3e31e..7b9171b803 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -24,3 +24,20 @@ #JoinControllers=cpu,cpuacct #RuntimeWatchdogSec=0 #ShutdownWatchdogSec=10min +#CapabilityBoundingSet= +#DefaultLimitCPU= +#DefaultLimitFSIZE= +#DefaultLimitDATA= +#DefaultLimitSTACK= +#DefaultLimitCORE= +#DefaultLimitRSS= +#DefaultLimitNOFILE= +#DefaultLimitAS= +#DefaultLimitNPROC= +#DefaultLimitMEMLOCK= +#DefaultLimitLOCKS= +#DefaultLimitSIGPENDING= +#DefaultLimitMSGQUEUE= +#DefaultLimitNICE= +#DefaultLimitRTPRIO= +#DefaultLimitRTTIME= |