#include "bus-errors.h"
#include "utf8.h"
#include "path-util.h"
+#include "syscall-list.h"
#ifndef HAVE_SYSV_COMPAT
int config_parse_warn_compat(
return 0;
}
-int config_parse_unit_names(
- const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- Unit *u = userdata;
- char *w;
- size_t l;
- char *state;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- char *t, *k;
- int r;
-
- t = strndup(w, l);
- if (!t)
- return -ENOMEM;
-
- k = unit_name_printf(u, t);
- free(t);
- if (!k)
- return -ENOMEM;
-
- r = unit_merge_by_name(u, k);
- if (r < 0)
- log_error("Failed to add name %s, ignoring: %s", k, strerror(-r));
-
- free(k);
- }
-
- return 0;
-}
-
int config_parse_unit_string_printf(
const char *filename,
unsigned line,
DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier");
DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier");
-int config_parse_facility(
- const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
-
- int *o = data, x;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if ((x = log_facility_unshifted_from_string(rvalue)) < 0) {
- log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue);
- return 0;
- }
-
- *o = (x << 3) | LOG_PRI(*o);
-
- return 0;
-}
-
-int config_parse_level(
- const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
-
- int *o = data, x;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if ((x = log_level_from_string(rvalue)) < 0) {
- log_error("[%s:%u] Failed to parse log level, ignoring: %s", filename, line, rvalue);
- return 0;
- }
-
- *o = (*o & LOG_FACMASK) | x;
- return 0;
-}
-
int config_parse_exec_io_class(
const char *filename,
unsigned line,
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;
return 0;
}
+int config_parse_service_timeout(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Service *s = userdata;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(s);
+
+ r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+ if (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(
const char *filename,
unsigned line,
}
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;
}
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) {
}
/* 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;
/* 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
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;
}
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;
/* 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;
}
r = open_follow(&filename, &f, symlink_names, &id);
if (r < 0) {
- char *sn;
-
free(filename);
filename = NULL;
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;
}
}
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) {
goto finish;
}
- zero(st);
if (fstat(fileno(f), &st) < 0) {
r = -errno;
goto finish;
/* 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 */
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)
/* 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) {
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);
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);
{ config_parse_limit, "LIMIT" },
{ config_parse_unit_cgroup, "CGROUP [...]" },
{ config_parse_unit_deps, "UNIT [...]" },
- { config_parse_unit_names, "UNIT [...]" },
{ config_parse_exec, "PATH [ARGUMENT [...]]" },
{ config_parse_service_type, "SERVICETYPE" },
{ config_parse_service_restart, "SERVICERESTART" },