[Buildroot] [RFC 1/1] package/skeleton-init-systemd: ignore credential services

Gaël PORTAY gael.portay+rtone at gmail.com
Tue Feb 4 09:29:15 UTC 2025


TL;DR; This ignores the tmpfiles.d credential services since these lines
import credential contents from the host. It intends to shutdown the
error attached in the end of the commit message.

Note: The issue happens if the host system has credential services (i.e.
CREDENTIALS_DIRECTORY or ENCRYPTED_CREDENTIALS_DIRECTORY set in its host
environment) and if the target is setup to run systemd on a read-only
filesystem:

	BR2_INIT_SYSTEMD=y
	BR2_INIT_SYSTEMD_POPULATE_TMPFILES=y

Let's step back a bit..

The script package/skeleton-init-systemd/fakeroot_tmpfiles.sh has been
introduced by the commit d18176396a (package/skeleton-systemd: host the
tmpfiles preparation script) to address at buildtime the creation of the
runtime tmpfiles for the targets using read-only filesystem. It uses
tmpfiles.d underneath.

systemd has introduced Credentials in tmpfiles.d since a v252[3]. The
lines starting by a charet[4], reads data from the credential host
service defined by the name set in the 6th argument.

See tmpfiles.d(5)[1]:

        If the caret character ("^") is used, the argument (i.e. 6th)
        column takes a service credential name to read the argument data
        from. See System and Service Credentials[2] for details about
        the credentials concept. This modifier is only supported on line
        types that can write file contents, i.e. f, f+, w, w+. This is
        useful for writing arbitrary files with contents sourced from
        elsewhere, including from VM or container managers further up.
        If the specified credential is not set for the systemd-tmpfiles
        service, the line is silently skipped. If "^" and "~" are
        combined Base64 decoding is applied to the credential contents.

The credentials data are pulled by the tmpfiles.d provision.conf[5] if
the either CREDENTIALS_DIRECTORY or ENCRYPTED_CREDENTIALS_DIRECTORY are
set in the user environment; the files located in these directories
belong to root and thus cause tmpfiles.d to end with a Permission
denied.

	gportay at archlinux ~ $ echo $CREDENTIALS_DIRECTORY
	/run/credentials/getty at tty1.service

This fixes the error below attached below by ignoring any credential
services by unsetting the two credential environment variables
CREDENTIALS_DIRECTORY and ENCRYPTED_CREDENTIALS_DIRECTORY before running
tmpfiles.d.

Fixes:

	>>>   Generating filesystem image rootfs.ext2
	(... TMPDIR= TEMP= TMP= /home/gportay/src/buildroot/output/host/bin/systemd-tmpfiles --create --boot --root=/home/gportay/src/buildroot/output/build/buildroot-fs/ext2/target --exclude-prefix=/dev --exclude-prefix=/proc --exclude-prefix=/run --exclude-prefix=/sys --exclude-prefix=/tmp --exclude-prefix=/mnt -)
	ignored spec: h /var/log/journal/%m - - - - +C
	Failed to read credential 'login.motd': Permission denied
	Failed to read credential 'login.issue': Permission denied
	Failed to read credential 'network.hosts': Permission denied
	Failed to read credential 'ssh.authorized_keys.root': Permission denied
	ignored spec: x /var/tmp/systemd-private-%b-*
	ignored spec: X /var/tmp/systemd-private-%b-*/tmp
	ignored spec: x  /var/lib/systemd/coredump/.#core*.%b*
	ignored spec: z /var/log/journal/%m 2755 root systemd-journal - -
	ignored spec: z /var/log/journal/%m/system.journal 0640 root systemd-journal - -

	gportay at archlinux ~ $ systemctl --version
	systemd 256 (256.8-1-arch)
	+PAM +AUDIT -SELINUX -APPARMOR -IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP -SYSVINIT +LIBARCHIVE

	gportay at archlinux ~ $ echo $CREDENTIALS_DIRECTORY
	/run/credentials/getty at tty1.service

Important: The issue happened on my setup for a while (256.8) and it has
silently disappeared without saying goodbye (257.2 as of today).
Therefore, I cannot reproduce it in a true situation as the environment
CREDENTIALS_DIRECTORY is not set anymore. I have no idea if it was an
host package misconfiguration, who knows. However, one can fake it using
the command below:

	CREDENTIALS_DIRECTORY=/run/credentials/getty at tty1.service make

[1]: https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html#Type%20Modifiers
[2]: https://systemd.io/CREDENTIALS/
[3]: https://github.com/systemd/systemd/commit/1d77721f30a821464cd715a63b89ef18419de7b0
[4]: https://github.com/systemd/systemd/commit/e52f6f6358e515f55c26c5aed1eb2dc1fbc8efec
[5]: https://github.com/systemd/systemd/blob/v256/tmpfiles.d/provision.conf

Signed-off-by: Gaël PORTAY <gael.portay+rtone at gmail.com>
---
Hello,

Despiste the fact the issue has gone, I do think the scripts should
sanitize the environment before running tmpfiles.d.

Note: I have not found a way to disable the credential with the CLI,
therefore, I came to the conclusion that unset the variables is the only
way to fix that issue.

Regards,
Gaël
 package/skeleton-init-systemd/fakeroot_tmpfiles.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/package/skeleton-init-systemd/fakeroot_tmpfiles.sh b/package/skeleton-init-systemd/fakeroot_tmpfiles.sh
index 8c28ccfa14..88dd27a006 100755
--- a/package/skeleton-init-systemd/fakeroot_tmpfiles.sh
+++ b/package/skeleton-init-systemd/fakeroot_tmpfiles.sh
@@ -30,6 +30,10 @@
 [ -n "${1-}" -a -d "${1-}"/usr/lib/tmpfiles.d ] ||
     { echo 1>&2 "$0: need ROOTFS argument"; exit 1; }
 
+# disable credential host services (since v252)
+unset CREDENTIALS_DIRECTORY
+unset ENCRYPTED_CREDENTIALS_DIRECTORY
+
 ${HOST_SYSTEMD_TMPFILES} --no-pager --cat-config --root="$1" |
     sed -e '/^[[:space:]]*#/d' -e 's,^[[:space:]]*,,' -e '/^$/d' |
     while read -r line; do
-- 
2.48.1



More information about the buildroot mailing list