dcavalca / rpms / systemd

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