]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: add integration test for unpriv mountfsd/nsresourced
authorLennart Poettering <lennart@poettering.net>
Tue, 23 Jan 2024 15:20:10 +0000 (16:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 6 Apr 2024 14:09:10 +0000 (16:09 +0200)
test/TEST-50-DISSECT/test.sh
test/test-functions
test/units/testsuite-50.sh

index 613bb086ce3b630fcf189657b9f68c1d42acc93b..b93697b73c75af417d912e46bcae80a2dc27fd5c 100755 (executable)
@@ -12,6 +12,15 @@ TEST_INSTALL_VERITY_MINIMAL=1
 # shellcheck source=test/test-functions
 . "${TEST_BASE_DIR:?}/test-functions"
 
+# On Ubuntu the BPF LSM is not enabled by default, so we need to do it via the
+# kernel command line on boot
+if [ "$LOOKS_LIKE_UBUNTU" = "yes" ]; then
+    KERNEL_OPTIONS=(
+        "lsm=lockdown,capability,landlock,yama,apparmor,bpf"
+    )
+    KERNEL_APPEND+=" ${KERNEL_OPTIONS[*]}"
+fi
+
 test_require_bin mksquashfs veritysetup sfdisk
 
 test_append_files() {
index a09092a5b030a852118ca2b9086f92327025a215..c62cf3d52182796088e53f58fc30b1426d0de1f1 100644 (file)
@@ -39,6 +39,8 @@ os_release=$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os
 # shellcheck source=/dev/null
 source "$os_release"
 [[ "$ID" == "debian" || " $ID_LIKE " == *" debian "* ]] && LOOKS_LIKE_DEBIAN=yes || LOOKS_LIKE_DEBIAN=no
+# shellcheck disable=SC2034
+[[ "$ID" == "ubuntu" ]] && LOOKS_LIKE_UBUNTU=yes || LOOKS_LIKE_UBUNTU=no
 [[ "$ID" == "arch" || " $ID_LIKE " == *" arch "* ]] && LOOKS_LIKE_ARCH=yes || LOOKS_LIKE_ARCH=no
 [[ "$ID" == "fedora" ]] && LOOKS_LIKE_FEDORA=yes || LOOKS_LIKE_FEDORA=no
 [[ " $ID_LIKE " == *" suse "* ]] && LOOKS_LIKE_SUSE=yes || LOOKS_LIKE_SUSE=no
@@ -733,6 +735,7 @@ install_verity_minimal() {
         BASICTOOLS=(
             bash
             cat
+            echo
             grep
             mount
             sleep
index cd2d6aa7f7fa5f33eb003dda8afec64ae4e9c39d..9c2e6f354cadbeed9ff0eee1d1cb56c6ea62ac35 100755 (executable)
@@ -6,6 +6,9 @@
 set -eux
 set -o pipefail
 
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
 export SYSTEMD_LOG_LEVEL=debug
 
 cleanup_image_dir() {
@@ -798,6 +801,62 @@ if command -v mksquashfs >/dev/null 2>&1; then
     (! test -f /usr/waldo)
 fi
 
+if test -f /usr/lib/systemd/system/systemd-mountfsd.socket -a -f /usr/lib/systemd/system/systemd-nsresourced.socket && \
+        command -v command -v mksquashfs >/dev/null 2>&1 && \
+        grep -q bpf /sys/kernel/security/lsm && \
+        test "$(find /usr/lib*  -name libbpf.so.1 2>/dev/null)" != "" ; then
+
+    cleanunprivfiles() {
+        umount -R /tmp/unpriv/mount
+        rmdir /tmp/unpriv
+        rm -f /tmp/test-50-unpriv-privkey.key /tmp/test-50-unpriv-cert.crt /run/verity.d/test-50-unpriv-cert.crt
+        rm -f /var/tmp/unpriv.raw /tmp/unpriv.raw.mtree /tmp/unpriv2.raw.mtree
+        rm -f /tmp/unpriv.out /tmp/unpriv.out2 /tmp/unpriv.out3
+    }
+
+    trap cleanunprivfiles EXIT
+
+    systemctl start systemd-mountfsd.socket systemd-nsresourced.socket
+
+    openssl req -config "$OPENSSL_CONFIG" -subj="/CN=waldo" -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout /tmp/test-50-unpriv-privkey.key -out /tmp/test-50-unpriv-cert.crt
+
+    systemd-dissect --mkdir --mount "${image}.raw" /tmp/unpriv/mount
+    SYSTEMD_REPART_OVERRIDE_FSTYPE=squashfs systemd-repart -P -s /tmp/unpriv/mount --certificate=/tmp/test-50-unpriv-cert.crt --private-key=/tmp/test-50-unpriv-privkey.key /var/tmp/unpriv.raw
+    systemd-dissect --rmdir --umount /tmp/unpriv/mount
+
+    systemd-dissect --image-policy='root=unprotected:=absent+unused' /var/tmp/unpriv.raw
+    systemd-dissect --image-policy='root=unprotected:=absent+unused' --mtree /var/tmp/unpriv.raw | tee /tmp/unpriv.raw.mtree
+
+    # Run unpriv, should fail due to lack of privs
+    (! runas testuser systemd-dissect /var/tmp/unpriv.raw )
+    (! runas testuser systemd-dissect --mtree /var/tmp/unpriv.raw )
+
+    # Install key in keychain
+    cp /tmp/test-50-unpriv-cert.crt /run/verity.d
+
+    # Now run unpriv again, should be OK now.
+    runas testuser systemd-dissect /var/tmp/unpriv.raw
+    runas testuser systemd-dissect --mtree /var/tmp/unpriv.raw | tee /tmp/unpriv2.raw.mtree
+
+    # Check that unpriv and priv run yielded same results
+    cmp /tmp/unpriv.raw.mtree /tmp/unpriv2.raw.mtree
+
+    # Make sure nspawn works unpriv, too (for now do not nest)
+    if ! systemd-detect-virt -c ; then
+        systemd-nspawn --pipe -i /var/tmp/unpriv.raw --read-only echo thisisatest > /tmp/unpriv.out
+        echo thisisatest | cmp /tmp/unpriv.out -
+
+        # The unpriv user has no rights to lock the image or write to it. Let's
+        # turn off both for this test, so that we don't have to copy the image
+        # around.
+        systemd-run -M testuser@ --user --pipe -p Environment=SYSTEMD_NSPAWN_LOCK=0 -p Delegate=1 -p DelegateSubgroup=supervisor -p Environment=SYSTEMD_LOG_LEVEL=debug --wait systemd-nspawn --keep-unit -i /var/tmp/unpriv.raw --read-only --pipe echo thisisatest > /tmp/unpriv.out2
+        echo thisisatest | cmp /tmp/unpriv.out2 -
+    fi
+
+    systemd-run -M testuser@ --user --pipe -p RootImage=/var/tmp/unpriv.raw -p PrivateUsers=1 --wait echo thisisatest > /tmp/unpriv.out3
+    echo thisisatest | cmp /tmp/unpriv.out3 -
+fi
+
 # Sneak in a couple of expected-to-fail invocations to cover
 # https://github.com/systemd/systemd/issues/29610
 (! systemd-run -P -p MountImages="/this/should/definitely/not/exist.img:/run/img2\:3:nosuid" false)