X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fload-fragment.c;h=10681307cfc2fe3d7d628a2f6dca6aa3faae590c;hp=1ca0dece678fed2a7a30b170fca48516f5e9fa31;hb=8f0e73f250f4a397ea07d29a339bd7e64d077612;hpb=8ff290af3b7db00eef76bdec61fee4aca7d84d0b diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 1ca0dece6..10681307c 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( @@ -1910,7 +1917,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 +2008,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; + 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) { @@ -2047,21 +2136,24 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { } /* Try to open the file name, but don't if its a symlink */ - if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0) + fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) break; if (errno != ELOOP) return -errno; /* Hmm, so this is a symlink. Let's read the name, and follow it manually */ - if ((r = readlink_and_make_absolute(*filename, &target)) < 0) + r = readlink_and_make_absolute(*filename, &target); + if (r < 0) return r; free(*filename); *filename = target; } - if (!(f = fdopen(fd, "re"))) { + f = fdopen(fd, "re"); + if (!f) { r = -errno; close_nointr_nofail(fd); return r; @@ -2085,7 +2177,8 @@ static int merge_by_names(Unit **u, Set *names, const char *id) { /* First try to merge in the other name into our * unit */ - if ((r = unit_merge_by_name(*u, k)) < 0) { + r = unit_merge_by_name(*u, k); + if (r < 0) { Unit *other; /* Hmm, we couldn't merge the other unit into @@ -2095,11 +2188,13 @@ static int merge_by_names(Unit **u, Set *names, const char *id) { other = manager_get_unit((*u)->manager, k); free(k); - if (other) - if ((r = unit_merge(other, *u)) >= 0) { + if (other) { + r = unit_merge(other, *u); + if (r >= 0) { *u = other; return merge_by_names(u, names, NULL); } + } return r; } @@ -2130,12 +2225,14 @@ static int load_from_path(Unit *u, const char *path) { if (path_is_absolute(path)) { - if (!(filename = strdup(path))) { + filename = strdup(path); + if (!filename) { r = -ENOMEM; goto finish; } - if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) { + r = open_follow(&filename, &f, symlink_names, &id); + if (r < 0) { free(filename); filename = NULL; @@ -2151,7 +2248,8 @@ static int load_from_path(Unit *u, const char *path) { /* Instead of opening the path right away, we manually * follow all symlinks and add their name to our unit * name set while doing so */ - if (!(filename = path_make_absolute(path, *p))) { + filename = path_make_absolute(path, *p); + if (!filename) { r = -ENOMEM; goto finish; } @@ -2163,8 +2261,6 @@ static int load_from_path(Unit *u, const char *path) { r = open_follow(&filename, &f, symlink_names, &id); if (r < 0) { - char *sn; - free(filename); filename = NULL; @@ -2172,9 +2268,7 @@ static int load_from_path(Unit *u, const char *path) { goto finish; /* Empty the symlink names for the next run */ - while ((sn = set_steal_first(symlink_names))) - free(sn); - + set_clear_free(symlink_names); continue; } @@ -2189,7 +2283,8 @@ static int load_from_path(Unit *u, const char *path) { } merged = u; - if ((r = merge_by_names(&merged, symlink_names, id)) < 0) + r = merge_by_names(&merged, symlink_names, id); + if (r < 0) goto finish; if (merged != u) { @@ -2198,7 +2293,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; @@ -2252,7 +2346,8 @@ int unit_load_fragment(Unit *u) { /* First, try to find the unit under its id. We always look * for unit files in the default directories, to make it easy * to override things by placing things in /etc/systemd/system */ - if ((r = load_from_path(u, u->id)) < 0) + r = load_from_path(u, u->id); + if (r < 0) return r; /* Try to find an alias we can load this with */ @@ -2262,7 +2357,8 @@ int unit_load_fragment(Unit *u) { if (t == u->id) continue; - if ((r = load_from_path(u, t)) < 0) + r = load_from_path(u, t); + if (r < 0) return r; if (u->load_state != UNIT_STUB) @@ -2272,7 +2368,8 @@ int unit_load_fragment(Unit *u) { /* And now, try looking for it under the suggested (originally linked) path */ if (u->load_state == UNIT_STUB && u->fragment_path) { - if ((r = load_from_path(u, u->fragment_path)) < 0) + r = load_from_path(u, u->fragment_path); + if (r < 0) return r; if (u->load_state == UNIT_STUB) { @@ -2288,7 +2385,8 @@ int unit_load_fragment(Unit *u) { if (u->load_state == UNIT_STUB && u->instance) { char *k; - if (!(k = unit_name_template(u->id))) + k = unit_name_template(u->id); + if (!k) return -ENOMEM; r = load_from_path(u, k); @@ -2303,7 +2401,8 @@ int unit_load_fragment(Unit *u) { if (t == u->id) continue; - if (!(k = unit_name_template(t))) + k = unit_name_template(t); + if (!k) return -ENOMEM; r = load_from_path(u, k);