From f79283a86531e3bbf0854b5f126b7b291fadfb43 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 Mar 2019 19:09:09 +0100 Subject: [PATCH] core: expose SUID/SGID restriction as new unit setting RestrictSUIDSGID= (cherry picked from commit f69567cbe26d09eac9d387c0be0fc32c65a83ada) Related: #1687512 --- src/core/dbus-execute.c | 4 ++++ src/core/execute.c | 22 +++++++++++++++++++++ src/core/execute.h | 1 + src/core/load-fragment-gperf.gperf.m4 | 2 ++ src/shared/bus-unit-util.c | 2 +- test/fuzz/fuzz-unit-file/directives.service | 1 + 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 198f149210..e7c0b893d1 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -815,6 +815,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), @@ -1179,6 +1180,9 @@ int bus_exec_context_set_transient_property( if (streq(name, "RestrictRealtime")) return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error); + if (streq(name, "RestrictSUIDSGID")) + return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error); + if (streq(name, "DynamicUser")) return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error); diff --git a/src/core/execute.c b/src/core/execute.c index 56aa89e1ec..f012023224 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1366,6 +1366,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) { return context_has_address_families(c) || c->memory_deny_write_execute || c->restrict_realtime || + c->restrict_suid_sgid || exec_context_restrict_namespaces_set(c) || c->protect_kernel_tunables || c->protect_kernel_modules || @@ -1470,6 +1471,19 @@ static int apply_restrict_realtime(const Unit* u, const ExecContext *c) { return seccomp_restrict_realtime(); } +static int apply_restrict_suid_sgid(const Unit* u, const ExecContext *c) { + assert(u); + assert(c); + + if (!c->restrict_suid_sgid) + return 0; + + if (skip_seccomp_unavailable(u, "RestrictSUIDSGID=")) + return 0; + + return seccomp_restrict_suid_sgid(); +} + static int apply_protect_sysctl(const Unit *u, const ExecContext *c) { assert(u); assert(c); @@ -3404,6 +3418,12 @@ static int exec_child( return log_unit_error_errno(unit, r, "Failed to apply realtime restrictions: %m"); } + r = apply_restrict_suid_sgid(unit, context); + if (r < 0) { + *exit_status = EXIT_SECCOMP; + return log_unit_error_errno(unit, r, "Failed to apply SUID/SGID restrictions: %m"); + } + r = apply_restrict_namespaces(unit, context); if (r < 0) { *exit_status = EXIT_SECCOMP; @@ -4023,6 +4043,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { "%sIgnoreSIGPIPE: %s\n" "%sMemoryDenyWriteExecute: %s\n" "%sRestrictRealtime: %s\n" + "%sRestrictSUIDSGID: %s\n" "%sKeyringMode: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", @@ -4041,6 +4062,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { prefix, yes_no(c->ignore_sigpipe), prefix, yes_no(c->memory_deny_write_execute), prefix, yes_no(c->restrict_realtime), + prefix, yes_no(c->restrict_suid_sgid), prefix, exec_keyring_mode_to_string(c->keyring_mode)); if (c->root_image) diff --git a/src/core/execute.h b/src/core/execute.h index b2eb55f8f5..2266355962 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -245,6 +245,7 @@ struct ExecContext { * that the autofs logic detects that it belongs to us and we * don't enter a trigger loop. */ bool same_pgrp; + bool restrict_suid_sgid; unsigned long personality; bool lock_personality; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index cdf4d14c4e..49e938d0ce 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -76,6 +76,7 @@ $1.SystemCallErrorNumber, config_parse_syscall_errno, 0, $1.MemoryDenyWriteExecute, config_parse_bool, 0, offsetof($1, exec_context.memory_deny_write_execute) $1.RestrictNamespaces, config_parse_restrict_namespaces, 0, offsetof($1, exec_context) $1.RestrictRealtime, config_parse_bool, 0, offsetof($1, exec_context.restrict_realtime) +$1.RestrictSUIDSGID, config_parse_bool, 0, offsetof($1, exec_context.restrict_suid_sgid) $1.RestrictAddressFamilies, config_parse_address_families, 0, offsetof($1, exec_context) $1.LockPersonality, config_parse_bool, 0, offsetof($1, exec_context.lock_personality)', `$1.SystemCallFilter, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 @@ -84,6 +85,7 @@ $1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CO $1.MemoryDenyWriteExecute, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.RestrictNamespaces, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.RestrictRealtime, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 +$1.RestrictSUIDSGID, config_parse_warn_compat, DISABLED_CONFIGURATION 0 $1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0 $1.LockPersonality, config_parse_warn_compat, DISABLED_CONFIGURATION, 0') $1.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 055edd6e22..3c42e97b7a 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -697,7 +697,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con "PrivateMounts", "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups", - "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality")) + "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality" "RestrictSUIDSGID")) return bus_append_parse_boolean(m, field, eq); diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index d8d1fc68b8..eab1820e20 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -849,6 +849,7 @@ ReserveVT= RestrictAddressFamilies= RestrictNamespaces= RestrictRealtime= +RestrictSUIDSGID= RuntimeDirectory= RuntimeDirectoryMode= RuntimeDirectoryPreserve=