[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