summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjuergbi <j@bitron.ch>2018-03-21 23:41:19 +0100
committerLennart Poettering <lennart@poettering.net>2018-03-21 23:41:19 +0100
commit39362f6f7d23abf3a90dc99aae7299300b923a34 (patch)
tree16dbf7e912e7716eee06378731c9a5ae4f6e83eb
parent37cbc1d57992f49b3607bd66973dd30e0a8d1073 (diff)
downloadsystemd-39362f6f7d23abf3a90dc99aae7299300b923a34.tar.gz
main: add NoNewPrivileges config option (#8475)
This makes it possible to disable new privileges for the whole system.
-rw-r--r--man/systemd-system.conf.xml15
-rw-r--r--src/core/main.c9
-rw-r--r--src/core/system.conf.in1
-rw-r--r--test/fuzz-corpus/unit-file/directives.service1
4 files changed, 26 insertions, 0 deletions
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index fca9690092..5a308f275e 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -216,6 +216,21 @@
</varlistentry>
<varlistentry>
+ <term><varname>NoNewPrivileges=</varname></term>
+
+ <listitem><para>Takes a boolean argument. If true, ensures that PID 1
+ and all its children can never gain new privileges through
+ <citerefentry project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ (e.g. via setuid or setgid bits, or filesystem capabilities).
+ Defaults to false. General purpose distributions commonly rely
+ on executables with setuid or setgid bits and will thus not
+ function properly with this option enabled. Individual units
+ cannot disable this option.
+ Also see <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges Flag</ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>SystemCallArchitectures=</varname></term>
<listitem><para>Takes a space-separated list of architecture
diff --git a/src/core/main.c b/src/core/main.c
index a4d2cdf759..7ee3faabf4 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -127,6 +127,7 @@ static char *arg_watchdog_device = NULL;
static char **arg_default_environment = NULL;
static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
static uint64_t arg_capability_bounding_set = CAP_ALL;
+static bool arg_no_new_privs = false;
static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
static Set* arg_syscall_archs = NULL;
@@ -671,6 +672,7 @@ static int parse_config_file(void) {
{ "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
{ "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device },
{ "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set },
+ { "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs },
#if HAVE_SECCOMP
{ "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
#endif
@@ -1865,6 +1867,13 @@ static int initialize_runtime(
}
}
+ if (arg_system && arg_no_new_privs) {
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
+ *ret_error_message = "Failed to disable new privileges";
+ return log_emergency_errno(errno, "Failed to disable new privileges: %m");
+ }
+ }
+
if (arg_syscall_archs) {
r = enforce_syscall_archs(arg_syscall_archs);
if (r < 0) {
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index 08cbe529ba..f0a59a79a5 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -27,6 +27,7 @@
#RuntimeWatchdogSec=0
#ShutdownWatchdogSec=10min
#CapabilityBoundingSet=
+#NoNewPrivileges=no
#SystemCallArchitectures=
#TimerSlackNSec=
#DefaultTimerAccuracySec=1min
diff --git a/test/fuzz-corpus/unit-file/directives.service b/test/fuzz-corpus/unit-file/directives.service
index 0077ae739b..c2334d3b19 100644
--- a/test/fuzz-corpus/unit-file/directives.service
+++ b/test/fuzz-corpus/unit-file/directives.service
@@ -809,6 +809,7 @@ MountFlags=
NAME=
NAutoVTs=
Nice=
+NoNewPrivileges=
NotifyReady=
OOMScoreAdjust=
Overlay=