Fixes #6685.
✓ SupplementaryGroups=
✓ Nice=
✓ OOMScoreAdjust=
+✓ CoredumpFilter=
✓ IOSchedulingClass=
✓ IOSchedulingPriority=
✓ CPUSchedulingPolicy=
to 0022.</para></listitem>
</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>
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,
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),
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;
}
}
+ 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)
"%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",
#include <sys/capability.h>
#include "cgroup-util.h"
+#include "coredump-util.h"
#include "cpu-set-util.h"
#include "exec-util.h"
#include "fdset.h"
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;
int ioprio;
int cpu_sched_policy;
int cpu_sched_priority;
+ uint64_t coredump_filter;
CPUSet cpu_set;
NUMAPolicy numa_policy;
$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)
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,
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);
#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"
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;
"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);
(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;
#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] = {
*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);
+}
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);
BlockIOWriteBandwidth=
Broadcast=
BusName=
+CoredumpFilter=
CPUAccounting=
CPUQuota=
CPUShares=