diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 17ca70f6bb9..b1b572c8758 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2496,11 +2496,12 @@ BindReadOnlyPaths=/var/lib/systemd RestrictFileSystems= - Restricts the set of filesystems processes of this unit can open files on. Takes a space-separated - list of filesystem names. Any filesystem listed is made accessible to the unit's processes, access to filesystem - types not listed is prohibited (allow-listing). If the first character of the list is ~, the - effect is inverted: access to the filesystems listed is prohibited (deny-listing). If the empty string is assigned, - access to filesystems is not restricted. + Restricts the set of filesystems processes of this unit can open files on. Takes a + comma- or space-separated list of filesystem names. Any filesystem listed is made accessible to the + unit's processes, access to filesystem types not listed is prohibited (allow-listing). If the first + character of the list is ~, the effect is inverted: access to the filesystems listed + is prohibited (deny-listing). If the empty string is assigned, access to filesystems is not + restricted. If you specify both types of this option (i.e. allow-listing and deny-listing), the first encountered will take precedence and will dictate the default action (allow access to the filesystem or deny it). Then the next occurrences @@ -3197,8 +3198,8 @@ SystemCallErrorNumber=EPERM SystemCallLog= - Takes a space-separated list of system call names. If this setting is used, all - system calls executed by the unit processes for the listed ones will be logged. If the first + Takes a comma- or space-separated list of system call names. If this setting is used, + all system calls executed by the unit processes for the listed ones will be logged. If the first character of the list is ~, the effect is inverted: all system calls except the listed system calls will be logged. This feature makes use of the Secure Computing Mode 2 interfaces of the kernel ('seccomp filtering') and is useful for auditing or setting up a minimal sandboxing diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index 4e908f150ec..c1f009be03a 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -992,11 +992,11 @@ SocketBindDeny=any RestrictNetworkInterfaces= - Takes a list of space-separated network interface names. This option restricts the network - interfaces that processes of this unit can use. By default, processes can only use the network interfaces - listed (allow-list). If the first character of the rule is ~, the effect is inverted: - the processes can only use network interfaces not listed (deny-list). - + Takes a comma- or space-separated list of network interface names. This option restricts the + network interfaces that processes of this unit can use. By default, processes can only use the network + interfaces listed (allow-list). If the first character of the rule is ~, the effect is + inverted: the processes can only use network interfaces not listed (deny-list). Note: to specify + an interface with a comma in the name, use quotes. This option can appear multiple times, in which case the network interface names are merged. If the empty string is assigned the set is reset, all prior assignments will have not effect. @@ -1011,6 +1011,7 @@ SocketBindDeny=any The loopback interface ("lo") is not treated in any special way, you have to configure it explicitly in the unit file. + Example 1: allow-list RestrictNetworkInterfaces=eth1 diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 168bdf10c13..e7cd3125560 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -1966,7 +1966,9 @@ int bus_cgroup_set_property( } } - joined = strv_join(l, " "); + /* Quote the names, so that names containing the separators (a comma is a valid character in + * an interface name) or quotes survive being read back from the drop-in. */ + joined = unit_concat_strv(l, UNIT_ESCAPE_EXEC_SYNTAX); if (!joined) return -ENOMEM; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 7bc7c296d3f..cd4f1de2b56 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3433,7 +3433,7 @@ int config_parse_syscall_log( for (;;) { _cleanup_free_ char *word = NULL; - r = extract_first_word(&p, &word, NULL, 0); + r = extract_first_word(&p, &word, /* separators= */ WHITESPACE ",", 0); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -3686,7 +3686,7 @@ int config_parse_restrict_filesystems( for (const char *p = rvalue;;) { _cleanup_free_ char *word = NULL; - r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); + r = extract_first_word(&p, &word, /* separators= */ WHITESPACE ",", EXTRACT_UNQUOTE); if (r == 0) break; if (r == -ENOMEM) @@ -6015,7 +6015,7 @@ int config_parse_restrict_network_interfaces( for (const char *p = rvalue;;) { _cleanup_free_ char *word = NULL; - r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); + r = extract_first_word(&p, &word, /* separators= */ WHITESPACE ",", EXTRACT_UNQUOTE); if (r == 0) break; if (r == -ENOMEM) diff --git a/test/integration-tests/TEST-62-RESTRICT-IFACES/TEST-62-RESTRICT-IFACES.units/TEST-62-RESTRICT-IFACES-5.service b/test/integration-tests/TEST-62-RESTRICT-IFACES/TEST-62-RESTRICT-IFACES.units/TEST-62-RESTRICT-IFACES-5.service index 20fe4629189..bd98a348e4f 100644 --- a/test/integration-tests/TEST-62-RESTRICT-IFACES/TEST-62-RESTRICT-IFACES.units/TEST-62-RESTRICT-IFACES-5.service +++ b/test/integration-tests/TEST-62-RESTRICT-IFACES/TEST-62-RESTRICT-IFACES.units/TEST-62-RESTRICT-IFACES-5.service @@ -7,5 +7,6 @@ ExecStart=bash -c 'ping -c 1 -W 0.2 192.168.113.5' ExecStart=bash -c '! ping -c 1 -W 0.2 192.168.113.9' RestrictNetworkInterfaces=veth0 RestrictNetworkInterfaces=veth0 veth1 +RestrictNetworkInterfaces=veth0,veth1 RestrictNetworkInterfaces=~veth0 Type=oneshot diff --git a/test/units/TEST-07-PID1.exec-context.sh b/test/units/TEST-07-PID1.exec-context.sh index 14cc49f2923..a2cadae1cf3 100755 --- a/test/units/TEST-07-PID1.exec-context.sh +++ b/test/units/TEST-07-PID1.exec-context.sh @@ -348,6 +348,7 @@ if [[ ! -v ASAN_OPTIONS ]] && systemctl --version | grep "+BPF_FRAMEWORK" && ker ROOTFS="$(df --output=fstype /usr/bin | sed --quiet 2p)" systemd-run --wait --pipe -p RestrictFileSystems="" ls / systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS foo bar" ls / + systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS,foo,bar" ls / (! systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS" ls /proc) (! systemd-run --wait --pipe -p GCOV_ERROR_LOG=/dev/null -p RestrictFileSystems="foo" ls /) systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS foo bar baz proc" ls /proc diff --git a/test/units/TEST-62-RESTRICT-IFACES.sh b/test/units/TEST-62-RESTRICT-IFACES.sh index 6ed61aea2ec..2bc1d7d8a1d 100755 --- a/test/units/TEST-62-RESTRICT-IFACES.sh +++ b/test/units/TEST-62-RESTRICT-IFACES.sh @@ -49,4 +49,14 @@ systemctl start --wait TEST-62-RESTRICT-IFACES-3.service systemctl start --wait TEST-62-RESTRICT-IFACES-4.service systemctl start --wait TEST-62-RESTRICT-IFACES-5.service +# An interface name containing a comma must survive the transient drop-in and a daemon-reload. +# The interface does not need to exist, unknown names are ignored with a warning. +systemd-run --unit=TEST-62-RESTRICT-IFACES-transient.service \ + -p 'RestrictNetworkInterfaces=~"veth,comma"' \ + sleep infinity +test "$(systemctl show -P RestrictNetworkInterfaces TEST-62-RESTRICT-IFACES-transient.service)" = '~veth,comma' +systemctl daemon-reload +test "$(systemctl show -P RestrictNetworkInterfaces TEST-62-RESTRICT-IFACES-transient.service)" = '~veth,comma' +systemctl stop TEST-62-RESTRICT-IFACES-transient.service + touch /testok