X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fload-fragment.c;h=1f3da70aca34337bdd20383b0bcbf77f7be2c1ce;hb=faa368e3376cb5e3e3c27550fdde652f1d3c9584;hp=e0e42acbb4966f8eb7cebbbf8f9cc9349710cea5;hpb=9946996cda11a18b44d82344676e5a0e96339408;p=elogind.git diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index e0e42acbb..1f3da70ac 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -45,6 +45,7 @@ #include "bus-errors.h" #include "utf8.h" #include "path-util.h" +#include "syscall-list.h" #ifndef HAVE_SYSV_COMPAT int config_parse_warn_compat( @@ -879,7 +880,7 @@ int config_parse_bounding_set( if (r < 0) { log_error("[%s:%u] Failed to parse capability bounding set, ignoring: %s", filename, line, rvalue); - return 0; + continue; } sum |= ((uint64_t) 1ULL) << (uint64_t) cap; @@ -1375,10 +1376,16 @@ int config_parse_service_timeout( r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata); - if (!r) - s->timeout_defined = true; + if (r) + return r; - return r; + if (streq(lvalue, "TimeoutSec")) { + s->start_timeout_defined = true; + s->timeout_stop_usec = s->timeout_start_usec; + } else if (streq(lvalue, "TimeoutStartSec")) + s->start_timeout_defined = true; + + return 0; } int config_parse_unit_env_file( @@ -1462,6 +1469,7 @@ int config_parse_unit_condition_path( Unit *u = data; bool trigger, negate; Condition *c; + _cleanup_free_ char *p = NULL; assert(filename); assert(lvalue); @@ -1476,12 +1484,16 @@ int config_parse_unit_condition_path( if (negate) rvalue++; - if (!path_is_absolute(rvalue)) { - log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue); + p = unit_full_printf(u, rvalue); + if (!p) + return -ENOMEM; + + if (!path_is_absolute(p)) { + log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, p); return 0; } - c = condition_new(cond, rvalue, trigger, negate); + c = condition_new(cond, p, trigger, negate); if (!c) return -ENOMEM; @@ -1503,21 +1515,29 @@ int config_parse_unit_condition_string( Unit *u = data; bool trigger, negate; Condition *c; + _cleanup_free_ char *s = NULL; assert(filename); assert(lvalue); assert(rvalue); assert(data); - if ((trigger = rvalue[0] == '|')) + trigger = rvalue[0] == '|'; + if (trigger) rvalue++; - if ((negate = rvalue[0] == '!')) + negate = rvalue[0] == '!'; + if (negate) rvalue++; - if (!(c = condition_new(cond, rvalue, trigger, negate))) + s = unit_full_printf(u, rvalue); + if (!s) return -ENOMEM; + c = condition_new(cond, s, trigger, negate); + if (!c) + return log_oom(); + LIST_PREPEND(Condition, conditions, u->conditions, c); return 0; } @@ -1910,7 +1930,7 @@ int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const } if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) { - log_error("[%s:%u] Failed to parse block IO bandwith value, ignoring: %s", filename, line, rvalue); + log_error("[%s:%u] Failed to parse block IO bandwidth value, ignoring: %s", filename, line, rvalue); strv_free(l); return 0; } @@ -2001,6 +2021,88 @@ int config_parse_documentation( return r; } +static void syscall_set(uint32_t *p, int nr) { + p[nr >> 4] |= 1 << (nr & 31); +} + +static void syscall_unset(uint32_t *p, int nr) { + p[nr >> 4] &= ~(1 << (nr & 31)); +} + +int config_parse_syscall_filter( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + Unit *u = userdata; + bool invert = false; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + if (rvalue[0] == '~') { + invert = true; + rvalue++; + } + + if (!c->syscall_filter) { + size_t n; + + n = (syscall_max() + 31) >> 4; + c->syscall_filter = new(uint32_t, n); + if (!c->syscall_filter) + return -ENOMEM; + + memset(c->syscall_filter, invert ? 0xFF : 0, n * sizeof(uint32_t)); + + /* Add these by default */ + syscall_set(c->syscall_filter, __NR_execve); + syscall_set(c->syscall_filter, __NR_rt_sigreturn); +#ifdef __NR_sigreturn + syscall_set(c->syscall_filter, __NR_sigreturn); +#endif + syscall_set(c->syscall_filter, __NR_exit_group); + syscall_set(c->syscall_filter, __NR_exit); + } + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + int id; + char *t; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + id = syscall_from_name(t); + free(t); + + if (id < 0) { + log_error("[%s:%u] Failed to parse syscall, ignoring: %s", filename, line, rvalue); + continue; + } + + if (invert) + syscall_unset(c->syscall_filter, id); + else + syscall_set(c->syscall_filter, id); + } + + c->no_new_privileges = true; + + return 0; +} + #define FOLLOW_MAX 8 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { @@ -2204,7 +2306,6 @@ static int load_from_path(Unit *u, const char *path) { goto finish; } - zero(st); if (fstat(fileno(f), &st) < 0) { r = -errno; goto finish;