diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-04-09 17:15:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-09 17:15:26 +0200 |
commit | f58921bde341d5ff07dcf8a350489275aa22e24a (patch) | |
tree | 7a825fb51fbf86032ac2119c4f34cfd707589907 | |
parent | e58cd39f63317fa0a8580aa2197a27a185b8c0af (diff) | |
parent | b94fb74baec4b7a61d97f6900815bb01b83da6f1 (diff) | |
download | systemd-f58921bde341d5ff07dcf8a350489275aa22e24a.tar.gz |
Merge pull request #15332 from keszybz/coredump-filter
CoredumpFilter=
-rw-r--r-- | docs/TRANSIENT-SETTINGS.md | 1 | ||||
-rw-r--r-- | man/systemd.exec.xml | 26 | ||||
-rw-r--r-- | src/basic/parse-util.c | 4 | ||||
-rw-r--r-- | src/basic/parse-util.h | 12 | ||||
-rw-r--r-- | src/core/dbus-execute.c | 63 | ||||
-rw-r--r-- | src/core/execute.c | 13 | ||||
-rw-r--r-- | src/core/execute.h | 3 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 1 | ||||
-rw-r--r-- | src/core/load-fragment.c | 39 | ||||
-rw-r--r-- | src/core/load-fragment.h | 1 | ||||
-rw-r--r-- | src/shared/bus-unit-util.c | 5 | ||||
-rw-r--r-- | src/shared/bus-util.c | 6 | ||||
-rw-r--r-- | src/shared/coredump-util.c | 74 | ||||
-rw-r--r-- | src/shared/coredump-util.h | 29 | ||||
-rw-r--r-- | src/shared/meson.build | 2 | ||||
-rw-r--r-- | src/test/meson.build | 4 | ||||
-rw-r--r-- | src/test/test-coredump-util.c | 78 | ||||
-rw-r--r-- | src/test/test-parse-util.c | 39 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.service | 1 |
19 files changed, 396 insertions, 5 deletions
diff --git a/docs/TRANSIENT-SETTINGS.md b/docs/TRANSIENT-SETTINGS.md index 271d8ab1e3..d5a8046676 100644 --- a/docs/TRANSIENT-SETTINGS.md +++ b/docs/TRANSIENT-SETTINGS.md @@ -114,6 +114,7 @@ All execution-related settings are available for transient units. ✓ SupplementaryGroups= ✓ Nice= ✓ OOMScoreAdjust= +✓ CoredumpFilter= ✓ IOSchedulingClass= ✓ IOSchedulingPriority= ✓ CPUSchedulingPolicy= diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 79a2c744c6..073d331e6d 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -657,6 +657,32 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting> </varlistentry> <varlistentry> + <term><varname>CoredumpFilter=</varname></term> + + <listitem><para>Controls which types of memory mappings will be saved if the process dumps core + (using the <filename>/proc/<replaceable>pid</replaceable>/coredump_filter</filename> file). Takes a + whitespace-separated combination of mapping type names or numbers (with the default base 16). Mapping + type names are <constant>private-anonymous</constant>, <constant>shared-anonymous</constant>, + <constant>private-file-backed</constant>, <constant>shared-file-backed</constant>, + <constant>elf-headers</constant>, <constant>private-huge</constant>, + <constant>shared-huge</constant>, <constant>private-dax</constant>, <constant>shared-dax</constant>, + and the special values <constant>all</constant> (all types) and <constant>default</constant> (the + kernel default of <literal><constant>private-anonymous</constant> + <constant>shared-anonymous</constant> <constant>elf-headers</constant> + <constant>private-huge</constant></literal>). See + <citerefentry><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry> for the + meaning of the mapping types. When specified multiple times, all specified masks are ORed. When not + set, or if the empty value is assigned, the inherited value is not changed.</para> + + <example> + <title>Add DAX pages to the dump filter</title> + + <programlisting>CoredumpFilter=default private-dax shared-dax</programlisting> + </example> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>KeyringMode=</varname></term> <listitem><para>Controls how the kernel session keyring is set up for the service (see <citerefentry diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index e0094b0f37..8de5cd5c56 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -395,7 +395,7 @@ int safe_atoi(const char *s, int *ret_i) { return 0; } -int safe_atollu(const char *s, long long unsigned *ret_llu) { +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) { char *x = NULL; unsigned long long l; @@ -404,7 +404,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { s += strspn(s, WHITESPACE); errno = 0; - l = strtoull(s, &x, 0); + l = strtoull(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 36d76ba576..970bdefbf0 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -28,7 +28,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) { } int safe_atoi(const char *s, int *ret_i); -int safe_atollu(const char *s, unsigned long long *ret_u); int safe_atolli(const char *s, long long int *ret_i); int safe_atou8(const char *s, uint8_t *ret); @@ -59,6 +58,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) { return safe_atoi(s, (int*) ret_i); } +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu); + +static inline int safe_atollu(const char *s, long long unsigned *ret_llu) { + return safe_atollu_full(s, 0, ret_llu); +} + static inline int safe_atou64(const char *s, uint64_t *ret_u) { assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); return safe_atollu(s, (unsigned long long*) ret_u); @@ -69,6 +74,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) { return safe_atolli(s, (long long int*) ret_i); } +static inline int safe_atoux64(const char *s, uint64_t *ret) { + assert_cc(sizeof(int64_t) == sizeof(long long unsigned)); + return safe_atollu_full(s, 16, (long long unsigned*) ret); +} + #if LONG_MAX == INT_MAX static inline int safe_atolu(const char *s, unsigned long *ret_u) { assert_cc(sizeof(unsigned long) == sizeof(unsigned)); diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 5696a60ba8..29b55c62eb 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -102,6 +102,7 @@ static int property_get_oom_score_adjust( ExecContext *c = userdata; int32_t n; + int r; assert(bus); assert(reply); @@ -113,13 +114,55 @@ static int property_get_oom_score_adjust( _cleanup_free_ char *t = NULL; n = 0; - if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) - safe_atoi32(t, &n); + r = read_one_line_file("/proc/self/oom_score_adj", &t); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/self/oom_score_adj, ignoring: %m"); + else { + r = safe_atoi32(t, &n); + if (r < 0) + log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/oom_score_adj, ignoring: %m", t); + } } return sd_bus_message_append(reply, "i", n); } +static int property_get_coredump_filter( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + uint64_t n; + int r; + + assert(bus); + assert(reply); + assert(c); + + if (c->coredump_filter_set) + n = c->coredump_filter; + else { + _cleanup_free_ char *t = NULL; + + n = COREDUMP_FILTER_MASK_DEFAULT; + r = read_one_line_file("/proc/self/coredump_filter", &t); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/self/coredump_filter, ignoring: %m"); + else { + r = safe_atoux64(t, &n); + if (r < 0) + log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/coredump_filter, ignoring: %m", t); + } + } + + return sd_bus_message_append(reply, "t", n); +} + static int property_get_nice( sd_bus *bus, const char *path, @@ -747,6 +790,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST), @@ -2190,6 +2234,21 @@ int bus_exec_context_set_transient_property( return 1; + } else if (streq(name, "CoredumpFilter")) { + uint64_t f; + + r = sd_bus_message_read(message, "t", &f); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->coredump_filter = f; + c->coredump_filter_set = true; + unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f); + } + + return 1; + } else if (streq(name, "EnvironmentFiles")) { _cleanup_free_ char *joined = NULL; diff --git a/src/core/execute.c b/src/core/execute.c index 8e1e77b4b2..c59acad4ce 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3323,6 +3323,14 @@ static int exec_child( } } + if (context->coredump_filter_set) { + r = set_coredump_filter(context->coredump_filter); + if (ERRNO_IS_PRIVILEGE(r)) + log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m"); + else if (r < 0) + return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m"); + } + if (context->nice_set) { r = setpriority_closest(context->nice); if (r < 0) @@ -4614,6 +4622,11 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { "%sOOMScoreAdjust: %i\n", prefix, c->oom_score_adjust); + if (c->coredump_filter_set) + fprintf(f, + "%sCoredumpFilter: 0x%"PRIx64"\n", + prefix, c->coredump_filter); + for (i = 0; i < RLIM_NLIMITS; i++) if (c->rlimit[i]) { fprintf(f, "%sLimit%s: " RLIM_FMT "\n", diff --git a/src/core/execute.h b/src/core/execute.h index 4baf5b1a40..f96a2915eb 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -14,6 +14,7 @@ typedef struct Manager Manager; #include <sys/capability.h> #include "cgroup-util.h" +#include "coredump-util.h" #include "cpu-set-util.h" #include "exec-util.h" #include "fdset.h" @@ -161,6 +162,7 @@ struct ExecContext { bool working_directory_home:1; bool oom_score_adjust_set:1; + bool coredump_filter_set:1; bool nice_set:1; bool ioprio_set:1; bool cpu_sched_set:1; @@ -179,6 +181,7 @@ struct ExecContext { int ioprio; int cpu_sched_policy; int cpu_sched_priority; + uint64_t coredump_filter; CPUSet cpu_set; NUMAPolicy numa_policy; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 69abdb65ba..165b9ca9c1 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -28,6 +28,7 @@ $1.Group, config_parse_user_group_compat, 0, $1.SupplementaryGroups, config_parse_user_group_strv_compat, 0, offsetof($1, exec_context.supplementary_groups) $1.Nice, config_parse_exec_nice, 0, offsetof($1, exec_context) $1.OOMScoreAdjust, config_parse_exec_oom_score_adjust, 0, offsetof($1, exec_context) +$1.CoredumpFilter, config_parse_exec_coredump_filter, 0, offsetof($1, exec_context) $1.IOSchedulingClass, config_parse_exec_io_class, 0, offsetof($1, exec_context) $1.IOSchedulingPriority, config_parse_exec_io_priority, 0, offsetof($1, exec_context) $1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0, offsetof($1, exec_context) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 646364eb89..b4d6c522e4 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -592,6 +592,45 @@ int config_parse_exec_oom_score_adjust( return 0; } +int config_parse_exec_coredump_filter( + 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) { + + ExecContext *c = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + c->coredump_filter = 0; + c->coredump_filter_set = false; + return 0; + } + + uint64_t f; + r = coredump_filter_mask_from_string(rvalue, &f); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse the CoredumpFilter=%s, ignoring: %m", rvalue); + return 0; + } + + c->coredump_filter |= f; + c->oom_score_adjust_set = true; + return 0; +} + int config_parse_exec( const char *unit, const char *filename, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index b6b46b2449..bc72ef7745 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -26,6 +26,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_socket_protocol); CONFIG_PARSER_PROTOTYPE(config_parse_socket_bind); CONFIG_PARSER_PROTOTYPE(config_parse_exec_nice); CONFIG_PARSER_PROTOTYPE(config_parse_exec_oom_score_adjust); +CONFIG_PARSER_PROTOTYPE(config_parse_exec_coredump_filter); CONFIG_PARSER_PROTOTYPE(config_parse_exec); CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout); CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_abort); diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index a30876c1a1..463a0ddb71 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -8,6 +8,7 @@ #include "cgroup-setup.h" #include "cgroup-util.h" #include "condition.h" +#include "coredump-util.h" #include "cpu-set-util.h" #include "escape.h" #include "exec-util.h" @@ -119,6 +120,7 @@ DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou); DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, coredump_filter_mask_from_string); static int bus_append_string(sd_bus_message *m, const char *field, const char *eq) { int r; @@ -898,6 +900,9 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con "OOMScoreAdjust")) return bus_append_safe_atoi(m, field, eq); + if (streq(field, "CoredumpFilter")) + return bus_append_coredump_filter_mask_from_string(m, field, eq); + if (streq(field, "Nice")) return bus_append_parse_nice(m, field, eq); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 05762c68a3..d107a06ce3 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -374,6 +374,12 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b (void) format_timespan(timespan, sizeof(timespan), u, 0); bus_print_property_value(name, expected_value, value, timespan); + } else if (streq(name, "CoredumpFilter")) { + char buf[STRLEN("0xFFFFFFFF")]; + + xsprintf(buf, "0x%"PRIx64, u); + bus_print_property_value(name, expected_value, value, buf); + } else if (streq(name, "RestrictNamespaces")) { _cleanup_free_ char *s = NULL; const char *result; diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c new file mode 100644 index 0000000000..67897414bc --- /dev/null +++ b/src/shared/coredump-util.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "coredump-util.h" +#include "extract-word.h" +#include "fileio.h" +#include "string-table.h" + +static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { + [COREDUMP_FILTER_PRIVATE_ANONYMOUS] = "private-anonymous", + [COREDUMP_FILTER_SHARED_ANONYMOUS] = "shared-anonymous", + [COREDUMP_FILTER_PRIVATE_FILE_BACKED] = "private-file-backed", + [COREDUMP_FILTER_SHARED_FILE_BACKED] = "shared-file-backed", + [COREDUMP_FILTER_ELF_HEADERS] = "elf-headers", + [COREDUMP_FILTER_PRIVATE_HUGE] = "private-huge", + [COREDUMP_FILTER_SHARED_HUGE] = "shared-huge", + [COREDUMP_FILTER_PRIVATE_DAX] = "private-dax", + [COREDUMP_FILTER_SHARED_DAX] = "shared-dax", +}; + +DEFINE_STRING_TABLE_LOOKUP(coredump_filter, CoredumpFilter); + +int coredump_filter_mask_from_string(const char *s, uint64_t *ret) { + uint64_t m = 0; + + assert(s); + assert(ret); + + for (;;) { + _cleanup_free_ char *n = NULL; + CoredumpFilter v; + int r; + + r = extract_first_word(&s, &n, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + + if (streq(n, "default")) { + m |= COREDUMP_FILTER_MASK_DEFAULT; + continue; + } + + if (streq(n, "all")) { + m = UINT64_MAX; + continue; + } + + v = coredump_filter_from_string(n); + if (v >= 0) { + m |= 1u << v; + continue; + } + + uint64_t x; + r = safe_atoux64(n, &x); + if (r < 0) + return r; + + m |= x; + } + + *ret = m; + return 0; +} + +int set_coredump_filter(uint64_t value) { + char t[STRLEN("0xFFFFFFFF")]; + + sprintf(t, "0x%"PRIx64, value); + + return write_string_file("/proc/self/coredump_filter", t, + WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER); +} diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h new file mode 100644 index 0000000000..ff2e511bf1 --- /dev/null +++ b/src/shared/coredump-util.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "macro.h" + +typedef enum CoredumpFilter { + COREDUMP_FILTER_PRIVATE_ANONYMOUS = 0, + COREDUMP_FILTER_SHARED_ANONYMOUS, + COREDUMP_FILTER_PRIVATE_FILE_BACKED, + COREDUMP_FILTER_SHARED_FILE_BACKED, + COREDUMP_FILTER_ELF_HEADERS, + COREDUMP_FILTER_PRIVATE_HUGE, + COREDUMP_FILTER_SHARED_HUGE, + COREDUMP_FILTER_PRIVATE_DAX, + COREDUMP_FILTER_SHARED_DAX, + _COREDUMP_FILTER_MAX, + _COREDUMP_FILTER_INVALID = -1, +} CoredumpFilter; + +#define COREDUMP_FILTER_MASK_DEFAULT (1u << COREDUMP_FILTER_PRIVATE_ANONYMOUS | \ + 1u << COREDUMP_FILTER_SHARED_ANONYMOUS | \ + 1u << COREDUMP_FILTER_ELF_HEADERS | \ + 1u << COREDUMP_FILTER_PRIVATE_HUGE) + +const char* coredump_filter_to_string(CoredumpFilter i) _const_; +CoredumpFilter coredump_filter_from_string(const char *s) _pure_; +int coredump_filter_mask_from_string(const char *s, uint64_t *ret); + +int set_coredump_filter(uint64_t value); diff --git a/src/shared/meson.build b/src/shared/meson.build index 45a723f363..d1832a1f53 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -51,6 +51,8 @@ shared_sources = files(''' condition.h conf-parser.c conf-parser.h + coredump-util.c + coredump-util.h cpu-set-util.c cpu-set-util.h crypt-util.c diff --git a/src/test/meson.build b/src/test/meson.build index 6297875c0d..a674d6cfe9 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -588,6 +588,10 @@ tests += [ [], []], + [['src/test/test-coredump-util.c'], + [], + []], + [['src/test/test-daemon.c'], [], []], diff --git a/src/test/test-coredump-util.c b/src/test/test-coredump-util.c new file mode 100644 index 0000000000..14a78007e3 --- /dev/null +++ b/src/test/test-coredump-util.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "coredump-util.h" +#include "macro.h" +#include "tests.h" + +static void test_coredump_filter_to_from_string(void) { + log_info("/* %s */", __func__); + + for (CoredumpFilter i = 0; i < _COREDUMP_FILTER_MAX; i++) { + const char *n; + + assert_se(n = coredump_filter_to_string(i)); + log_info("0x%x\t%s", 1<<i, n); + assert_se(coredump_filter_from_string(n) == i); + + uint64_t f; + assert_se(coredump_filter_mask_from_string(n, &f) == 0); + assert_se(f == 1u << i); + } +} + +static void test_coredump_filter_mask_from_string(void) { + log_info("/* %s */", __func__); + + uint64_t f; + assert_se(coredump_filter_mask_from_string("default", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string(" default\tdefault\tdefault ", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string("defaulta", &f) < 0); + assert_se(coredump_filter_mask_from_string("default defaulta default", &f) < 0); + assert_se(coredump_filter_mask_from_string("default default defaulta", &f) < 0); + + assert_se(coredump_filter_mask_from_string("private-anonymous default", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string("shared-file-backed shared-dax", &f) == 0); + assert_se(f == (1 << COREDUMP_FILTER_SHARED_FILE_BACKED | + 1 << COREDUMP_FILTER_SHARED_DAX)); + + assert_se(coredump_filter_mask_from_string("private-file-backed private-dax 0xF", &f) == 0); + assert_se(f == (1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED | + 1 << COREDUMP_FILTER_PRIVATE_DAX | + 0xF)); + + assert_se(coredump_filter_mask_from_string("11", &f) == 0); + assert_se(f == 0x11); + + assert_se(coredump_filter_mask_from_string("0x1101", &f) == 0); + assert_se(f == 0x1101); + + assert_se(coredump_filter_mask_from_string("0", &f) == 0); + assert_se(f == 0); + + assert_se(coredump_filter_mask_from_string("all", &f) == 0); + assert_se(FLAGS_SET(f, (1 << COREDUMP_FILTER_PRIVATE_ANONYMOUS | + 1 << COREDUMP_FILTER_SHARED_ANONYMOUS | + 1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED | + 1 << COREDUMP_FILTER_SHARED_FILE_BACKED | + 1 << COREDUMP_FILTER_ELF_HEADERS | + 1 << COREDUMP_FILTER_PRIVATE_HUGE | + 1 << COREDUMP_FILTER_SHARED_HUGE | + 1 << COREDUMP_FILTER_PRIVATE_DAX | + 1 << COREDUMP_FILTER_SHARED_DAX))); +} + +int main(int argc, char **argv) { + test_setup_logging(LOG_INFO); + + test_coredump_filter_to_from_string(); + test_coredump_filter_mask_from_string(); + + return 0; +} diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c index d732f402f0..1627bc747d 100644 --- a/src/test/test-parse-util.c +++ b/src/test/test-parse-util.c @@ -561,6 +561,44 @@ static void test_safe_atoi64(void) { assert_se(r == -EINVAL); } +static void test_safe_atoux64(void) { + int r; + uint64_t l; + + r = safe_atoux64("12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64(" 12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64("0x12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64("18446744073709551617", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64("-1", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64(" -1", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64("junk", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("123x", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("12.3", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("", &l); + assert_se(r == -EINVAL); +} + static void test_safe_atod(void) { int r; double d; @@ -838,6 +876,7 @@ int main(int argc, char *argv[]) { test_safe_atoux16(); test_safe_atou64(); test_safe_atoi64(); + test_safe_atoux64(); test_safe_atod(); test_parse_percent(); test_parse_percent_unbounded(); diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 45f8751971..98cddad349 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -44,6 +44,7 @@ BlockIOWeight= BlockIOWriteBandwidth= Broadcast= BusName= +CoredumpFilter= CPUAccounting= CPUQuota= CPUShares= |