diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 4 | ||||
-rw-r--r-- | src/core/load-fragment.c | 218 | ||||
-rw-r--r-- | src/core/load-fragment.h | 2 | ||||
-rw-r--r-- | src/core/main.c | 10 |
4 files changed, 177 insertions, 57 deletions
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 5b7954dbf9..75388659e3 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -58,7 +58,7 @@ $1.RestrictAddressFamilies, config_parse_address_families, 0, $1.SystemCallArchitectures, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0') -$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) +$1.LimitCPU, config_parse_sec_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) $1.LimitFSIZE, config_parse_bytes_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) $1.LimitDATA, config_parse_bytes_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit) $1.LimitSTACK, config_parse_bytes_limit, RLIMIT_STACK, offsetof($1, exec_context.rlimit) @@ -73,7 +73,7 @@ $1.LimitSIGPENDING, config_parse_limit, RLIMIT_SIGP $1.LimitMSGQUEUE, config_parse_bytes_limit, RLIMIT_MSGQUEUE, offsetof($1, exec_context.rlimit) $1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit) $1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit) -$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) +$1.LimitRTTIME, config_parse_usec_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) $1.ReadWriteDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_dirs) $1.ReadOnlyDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_dirs) $1.InaccessibleDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index a514052772..79cabd26e7 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -974,23 +974,22 @@ int config_parse_exec_secure_bits(const char *unit, return 0; } -int config_parse_bounding_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_bounding_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) { uint64_t *capability_bounding_set_drop = data; - uint64_t capability_bounding_set; + uint64_t capability_bounding_set, sum = 0; bool invert = false; - uint64_t sum = 0; - const char *prev; - const char *cur; + const char *p; assert(filename); assert(lvalue); @@ -1007,35 +1006,32 @@ int config_parse_bounding_set(const char *unit, * non-inverted everywhere to have a fully normalized * interface. */ - prev = cur = rvalue; + p = rvalue; for (;;) { _cleanup_free_ char *word = NULL; - int cap; - int r; + int cap, r; - r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES); + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); if (r == 0) break; if (r == -ENOMEM) return log_oom(); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage in bounding set, ignoring: %s", prev); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word, ignoring: %s", rvalue); break; } cap = capability_from_name(word); if (cap < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding set, ignoring: %s", word); - prev = cur; continue; } - sum |= ((uint64_t) 1ULL) << (uint64_t) cap; - prev = cur; + sum |= ((uint64_t) UINT64_C(1)) << (uint64_t) cap; } capability_bounding_set = invert ? ~sum : sum; - if (*capability_bounding_set_drop && capability_bounding_set) + if (*capability_bounding_set_drop != 0 && capability_bounding_set != 0) *capability_bounding_set_drop = ~(~*capability_bounding_set_drop | capability_bounding_set); else *capability_bounding_set_drop = ~capability_bounding_set; @@ -1043,19 +1039,21 @@ int config_parse_bounding_set(const char *unit, return 0; } -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) { +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) { struct rlimit **rl = data; - unsigned long long u; + rlim_t v; + int r; assert(filename); assert(lvalue); @@ -1065,15 +1063,22 @@ int config_parse_limit(const char *unit, rl += ltype; if (streq(rvalue, "infinity")) - u = (unsigned long long) RLIM_INFINITY; + v = RLIM_INFINITY; else { - int r; + uint64_t u; - r = safe_atollu(rvalue, &u); + /* setrlimit(2) suggests rlim_t is always 64bit on Linux. */ + assert_cc(sizeof(rlim_t) == sizeof(uint64_t)); + + r = safe_atou64(rvalue, &u); + if (r >= 0 && u >= (uint64_t) RLIM_INFINITY) + r = -ERANGE; if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); return 0; } + + v = (rlim_t) u; } if (!*rl) { @@ -1082,23 +1087,25 @@ int config_parse_limit(const char *unit, return log_oom(); } - (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u; + (*rl)->rlim_cur = (*rl)->rlim_max = v; return 0; } -int config_parse_bytes_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) { +int config_parse_bytes_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) { struct rlimit **rl = data; - uint64_t bytes; + rlim_t bytes; + int r; assert(filename); assert(lvalue); @@ -1108,15 +1115,120 @@ int config_parse_bytes_limit(const char *unit, rl += ltype; if (streq(rvalue, "infinity")) - bytes = (uint64_t) RLIM_INFINITY; + bytes = RLIM_INFINITY; else { - int r; + uint64_t u; + + r = parse_size(rvalue, 1024, &u); + if (r >= 0 && u >= (uint64_t) RLIM_INFINITY) + r = -ERANGE; + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); + return 0; + } + + bytes = (rlim_t) u; + } + + if (!*rl) { + *rl = new(struct rlimit, 1); + if (!*rl) + return log_oom(); + } + + (*rl)->rlim_cur = (*rl)->rlim_max = bytes; + return 0; +} + +int config_parse_sec_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) { + + struct rlimit **rl = data; + rlim_t seconds; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + seconds = RLIM_INFINITY; + else { + usec_t t; + + r = parse_sec(rvalue, &t); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); + return 0; + } + + if (t == USEC_INFINITY) + seconds = RLIM_INFINITY; + else + seconds = (rlim_t) (DIV_ROUND_UP(t, USEC_PER_SEC)); + } + + if (!*rl) { + *rl = new(struct rlimit, 1); + if (!*rl) + return log_oom(); + } + + (*rl)->rlim_cur = (*rl)->rlim_max = seconds; + return 0; +} - r = parse_size(rvalue, 1024, &bytes); + +int config_parse_usec_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) { + + struct rlimit **rl = data; + rlim_t useconds; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + useconds = RLIM_INFINITY; + else { + usec_t t; + + r = parse_time(rvalue, &t, 1); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue); return 0; } + + if (t == USEC_INFINITY) + useconds = RLIM_INFINITY; + else + useconds = (rlim_t) t; } if (!*rl) { @@ -1125,7 +1237,7 @@ int config_parse_bytes_limit(const char *unit, return log_oom(); } - (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) bytes; + (*rl)->rlim_cur = (*rl)->rlim_max = useconds; return 0; } diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 029775bb46..0cf821289c 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -57,6 +57,8 @@ int config_parse_exec_secure_bits(const char *unit, const char *filename, unsign int config_parse_bounding_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); int config_parse_bytes_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); +int config_parse_sec_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); +int config_parse_usec_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); int config_parse_sysv_priority(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_kill_signal(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_mount_flags(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); diff --git a/src/core/main.c b/src/core/main.c index 950315e857..a86080642d 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -682,8 +682,14 @@ static int parse_config_file(void) { const char *fn, *conf_dirs_nulstr; - fn = arg_running_as == MANAGER_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf"; - conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? CONF_DIRS_NULSTR("systemd/system.conf") : CONF_DIRS_NULSTR("systemd/user.conf"); + fn = arg_running_as == MANAGER_SYSTEM ? + PKGSYSCONFDIR "/system.conf" : + PKGSYSCONFDIR "/user.conf"; + + conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? + CONF_PATHS_NULSTR("systemd/system.conf.d") : + CONF_PATHS_NULSTR("systemd/user.conf.d"); + config_parse_many(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL); |