manager: add CoredumpFilter= setting

Fixes #6685.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-04-04 16:43:25 +02:00
parent b34612bd5a
commit ad21e542b2
13 changed files with 160 additions and 0 deletions

View File

@ -114,6 +114,7 @@ All execution-related settings are available for transient units.
✓ SupplementaryGroups=
✓ Nice=
✓ OOMScoreAdjust=
✓ CoredumpFilter=
✓ IOSchedulingClass=
✓ IOSchedulingPriority=
✓ CPUSchedulingPolicy=

View File

@ -656,6 +656,32 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
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>

View File

@ -120,6 +120,42 @@ static int property_get_oom_score_adjust(
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 +783,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),
@ -2189,6 +2226,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;

View File

@ -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",

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -373,6 +373,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;

View File

@ -2,6 +2,7 @@
#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] = {
@ -62,3 +63,12 @@ int coredump_filter_mask_from_string(const char *s, uint64_t *ret) {
*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);
}

View File

@ -25,3 +25,5 @@ typedef enum CoredumpFilter {
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);

View File

@ -44,6 +44,7 @@ BlockIOWeight=
BlockIOWriteBandwidth=
Broadcast=
BusName=
CoredumpFilter=
CPUAccounting=
CPUQuota=
CPUShares=