diff options
Diffstat (limited to 'test/units/TEST-22-TMPFILES.03.sh')
-rwxr-xr-x | test/units/TEST-22-TMPFILES.03.sh | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/test/units/TEST-22-TMPFILES.03.sh b/test/units/TEST-22-TMPFILES.03.sh new file mode 100755 index 0000000..d158498 --- /dev/null +++ b/test/units/TEST-22-TMPFILES.03.sh @@ -0,0 +1,275 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Basic tests for types creating/writing files +set -eux +set -o pipefail + +rm -fr /tmp/{f,F,w} +mkdir /tmp/{f,F,w} +touch /tmp/file-owned-by-root + +# +# 'f' +# +systemd-tmpfiles --dry-run --create - <<EOF +f /tmp/f/1 0644 - - - - +f /tmp/f/2 0644 - - - This string should be written +EOF + +test ! -e /tmp/f/1 +test ! -e /tmp/f/2 + +systemd-tmpfiles --create - <<EOF +f /tmp/f/1 0644 - - - - +f /tmp/f/2 0644 - - - This string should be written +EOF + +### '1' should exist and be empty +test -f /tmp/f/1; test ! -s /tmp/f/1 +test "$(stat -c %U:%G:%a /tmp/f/1)" = "root:root:644" + +test "$(stat -c %U:%G:%a /tmp/f/2)" = "root:root:644" +test "$(< /tmp/f/2)" = "This string should be written" + +### The perms are supposed to be updated even if the file already exists. +systemd-tmpfiles --create - <<EOF +f /tmp/f/1 0666 daemon daemon - This string should not be written +EOF + +# file should be empty +test ! -s /tmp/f/1 +test "$(stat -c %U:%G:%a /tmp/f/1)" = "daemon:daemon:666" + +### But we shouldn't try to set perms on an existing file which is not a +### regular one. +mkfifo /tmp/f/fifo +chmod 644 /tmp/f/fifo + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/f/fifo 0666 daemon daemon - This string should not be written +EOF + +test -p /tmp/f/fifo +test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644" + +### 'f' should not follow symlinks. +ln -s missing /tmp/f/dangling +ln -s /tmp/file-owned-by-root /tmp/f/symlink + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/f/dangling 0644 daemon daemon - - +f /tmp/f/symlink 0644 daemon daemon - - +EOF +test ! -e /tmp/f/missing +test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644" + +### Handle read-only filesystem gracefully: we shouldn't fail if the target +### already exists and have the correct perms. +mkdir /tmp/f/rw-fs +mkdir /tmp/f/ro-fs + +touch /tmp/f/rw-fs/foo +chmod 644 /tmp/f/rw-fs/foo + +mount -o bind,ro /tmp/f/rw-fs /tmp/f/ro-fs + +systemd-tmpfiles --create - <<EOF +f /tmp/f/ro-fs/foo 0644 - - - - This string should not be written +EOF +test -f /tmp/f/ro-fs/foo; test ! -s /tmp/f/ro-fs/foo + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/f/ro-fs/foo 0666 - - - - +EOF +test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644" + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/f/ro-fs/bar 0644 - - - - +EOF +test ! -e /tmp/f/ro-fs/bar + +### 'f' shouldn't follow unsafe paths. +mkdir /tmp/f/daemon +ln -s /root /tmp/f/daemon/unsafe-symlink +chown -R --no-dereference daemon:daemon /tmp/f/daemon + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/f/daemon/unsafe-symlink/exploit 0644 daemon daemon - - +EOF +test ! -e /tmp/f/daemon/unsafe-symlink/exploit + +# +# 'F' +# +echo "This should be truncated" >/tmp/F/truncated +echo "This should be truncated" >/tmp/F/truncated-with-content + +systemd-tmpfiles --create - <<EOF +F /tmp/F/created 0644 - - - - +F /tmp/F/created-with-content 0644 - - - new content +F /tmp/F/truncated 0666 daemon daemon - - +F /tmp/F/truncated-with-content 0666 daemon daemon - new content +EOF + +test -f /tmp/F/created; test ! -s /tmp/F/created +test -f /tmp/F/created-with-content +test "$(< /tmp/F/created-with-content)" = "new content" +test -f /tmp/F/truncated; test ! -s /tmp/F/truncated +test "$(stat -c %U:%G:%a /tmp/F/truncated)" = "daemon:daemon:666" +test -s /tmp/F/truncated-with-content +test "$(stat -c %U:%G:%a /tmp/F/truncated-with-content)" = "daemon:daemon:666" + +### We shouldn't try to truncate anything but regular files since the behavior is +### unspecified in the other cases. +mkfifo /tmp/F/fifo + +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/fifo 0644 - - - - +EOF + +test -p /tmp/F/fifo + +### 'F' should not follow symlinks. +ln -s missing /tmp/F/dangling +ln -s /tmp/file-owned-by-root /tmp/F/symlink + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/F/dangling 0644 daemon daemon - - +f /tmp/F/symlink 0644 daemon daemon - - +EOF +test ! -e /tmp/F/missing +test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644" + +### Handle read-only filesystem gracefully: we shouldn't fail if the target +### already exists and is empty. +mkdir /tmp/F/rw-fs +mkdir /tmp/F/ro-fs + +touch /tmp/F/rw-fs/foo +chmod 644 /tmp/F/rw-fs/foo + +mount -o bind,ro /tmp/F/rw-fs /tmp/F/ro-fs + +systemd-tmpfiles --create - <<EOF +F /tmp/F/ro-fs/foo 0644 - - - - +EOF +test -f /tmp/F/ro-fs/foo; test ! -s /tmp/F/ro-fs/foo + +echo "truncating is not allowed anymore" >/tmp/F/rw-fs/foo +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/ro-fs/foo 0644 - - - - +EOF + +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/ro-fs/foo 0644 - - - - This string should not be written +EOF +test -f /tmp/F/ro-fs/foo +grep -q 'truncating is not allowed' /tmp/F/ro-fs/foo + +# Trying to change the perms should fail. +: >/tmp/F/rw-fs/foo +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/ro-fs/foo 0666 - - - - +EOF +test "$(stat -c %U:%G:%a /tmp/F/ro-fs/foo)" = "root:root:644" + +### Try to create a new file. +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/ro-fs/bar 0644 - - - - +EOF +test ! -e /tmp/F/ro-fs/bar + +### 'F' shouldn't follow unsafe paths. +mkdir /tmp/F/daemon +ln -s /root /tmp/F/daemon/unsafe-symlink +chown -R --no-dereference daemon:daemon /tmp/F/daemon + +(! systemd-tmpfiles --create -) <<EOF +F /tmp/F/daemon/unsafe-symlink/exploit 0644 daemon daemon - - +EOF +test ! -e /tmp/F/daemon/unsafe-symlink/exploit + +# +# 'w' +# +touch /tmp/w/overwritten +touch /tmp/w/appended + +### nop if the target does not exist. +systemd-tmpfiles --dry-run --create - <<EOF +w /tmp/w/unexistent 0644 - - - new content +EOF +test ! -e /tmp/w/unexistent + +systemd-tmpfiles --create - <<EOF +w /tmp/w/unexistent 0644 - - - new content +EOF +test ! -e /tmp/w/unexistent + +### no argument given -> fails. +(! systemd-tmpfiles --create -) <<EOF +w /tmp/w/unexistent 0644 - - - - +EOF + +### write into an empty file. +systemd-tmpfiles --dry-run --create - <<EOF +w /tmp/w/overwritten 0644 - - - old content +EOF +test -f /tmp/w/overwritten +test -z "$(< /tmp/w/overwritten)" + +systemd-tmpfiles --create - <<EOF +w /tmp/w/overwritten 0644 - - - old content +EOF +test -f /tmp/w/overwritten +test "$(< /tmp/w/overwritten)" = "old content" + +### old content is overwritten +systemd-tmpfiles --dry-run --create - <<EOF +w /tmp/w/overwritten 0644 - - - new content +EOF +test -f /tmp/w/overwritten +test "$(< /tmp/w/overwritten)" = "old content" + +systemd-tmpfiles --create - <<EOF +w /tmp/w/overwritten 0644 - - - new content +EOF +test -f /tmp/w/overwritten +test "$(< /tmp/w/overwritten)" = "new content" + +### append lines +systemd-tmpfiles --create - <<EOF +w+ /tmp/w/appended 0644 - - - 1 +w+ /tmp/w/appended 0644 - - - 2\n +w+ /tmp/w/appended 0644 - - - 3 +EOF +test -f /tmp/w/appended +test "$(< /tmp/w/appended)" = "$(echo -ne '12\n3')" + +### writing into an 'exotic' file should be allowed. +systemd-tmpfiles --dry-run --create - <<EOF +w /dev/null - - - - new content +EOF + +systemd-tmpfiles --create - <<EOF +w /dev/null - - - - new content +EOF + +### 'w' follows symlinks +ln -s ./overwritten /tmp/w/symlink +systemd-tmpfiles --create - <<EOF +w /tmp/w/symlink - - - - $(readlink -e /tmp/w/symlink) +EOF +readlink -e /tmp/w/symlink +test "$(< /tmp/w/overwritten)" = "/tmp/w/overwritten" + +### 'w' shouldn't follow unsafe paths. +mkdir /tmp/w/daemon +ln -s /root /tmp/w/daemon/unsafe-symlink +chown -R --no-dereference daemon:daemon /tmp/w/daemon + +(! systemd-tmpfiles --create -) <<EOF +f /tmp/w/daemon/unsafe-symlink/exploit 0644 daemon daemon - - +EOF +test ! -e /tmp/w/daemon/unsafe-symlink/exploit |