core: Add ProtectHostname=private

This allows an option for systemd exec units to enable UTS namespaces
but not restrict changing hostname via seccomp. Thus, units can change
hostname without affecting the host.

Fixes: #30348
This commit is contained in:
Ryan Wilson
2024-12-06 13:34:04 -08:00
parent 6746f28854
commit cf48bde7ae
6 changed files with 70 additions and 9 deletions
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2016
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
LEGACY_HOSTNAME="$(hostname)"
HOSTNAME_FROM_SYSTEMD="$(hostnamectl hostname)"
testcase_yes() {
# hostnamectl calls SetHostname method via dbus socket which executes in homenamed
# in the init namespace. So hostnamectl is not affected by ProtectHostname=yes or
# private since sethostname() system call is executed in the init namespace.
#
# hostnamed does authentication based on UID via polkit so this guarantees admins
# can only set hostname.
(! systemd-run --wait -p ProtectHostname=yes hostname foo)
systemd-run --wait -p ProtectHostname=yes -p PrivateMounts=yes \
findmnt --mountpoint /proc/sys/kernel/hostname
}
testcase_private() {
systemd-run --wait -p ProtectHostnameEx=private \
-P bash -xec '
hostname foo
test "$(hostname)" = "foo"
'
# Verify host hostname is unchanged.
test "$(hostname)" = "$LEGACY_HOSTNAME"
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
# Verify /proc/sys/kernel/hostname is not bind mounted from host read-only.
(! systemd-run --wait -p ProtectHostnameEx=private -p PrivateMounts=yes \
findmnt --mountpoint /proc/sys/kernel/hostname)
}
run_testcases