[systemd-devel] tee-supplicant initrd startup before tpm2.target and dev-tpmrm0.device

Lennart Poettering lennart at poettering.net
Thu May 23 16:00:07 UTC 2024


On Do, 23.05.24 10:54, Mikko Rapeli (mikko.rapeli at linaro.org) wrote:

> Hi,
>
> I'm running in circles and failing to start optee userspace daemon tee-supplicant
> correctly with systemd in initrd.
>
> In certain firmware/HW configurations with optee and firmware TPM trusted application,
> the setup needs tee-supplicant to start in initrd userspace before the fTPM kernel
> module gets enumerated, but I'm failing to express this in the systemd
> service dependencies.
>
> TPM usage in firmware is being detected correctly and tpm2.target is queued correctly,
> but the dev-tpmrm0.device is not found since tee-supplicant at teepriv0.service is not
> getting started before it.
>
> optee kernel driver is loaded and working. /dev/teepriv0 is
> generated by udev but not

Note that udev does not generate device nodes. The kernel does. udev
just chmods/chown/acls it and maintains metadata about it.

> before dev-tpmrm0.device.
>
> tee-supplicant at .service:
>
> [Unit]
> Description=TEE Supplicant on %i
>
> [Service]
> User=root

This line is redundant.

> EnvironmentFile=- at sysconfdir@/default/tee-supplicant
> ExecStart=@sbindir@/tee-supplicant $OPTARGS
>
> [Install]
> WantedBy=basic.target

Usually you'd hook services into "sysinit.target" not
"basic.target". The job of "basic.target" is really do combine
sysinit.target (i.e. early-boot services), local-fs.target
(i.e. local mounts), swaps.target (swaps), sockets.target (well, you
guess it), and so on.

Hence, if you plug in services, use sysinit.target.

> udev rule is:
>
> KERNEL=="tee[0-9]*", MODE="0660", OWNER="root", GROUP="teeclnt", TAG+="systemd"
>
> # If a /dev/teepriv[0-9]* device is detected, start an instance of
> # tee-supplicant.service with the device name as parameter
> KERNEL=="teepriv[0-9]*", MODE="0660", OWNER="root", GROUP="teeclnt", \
>     TAG+="systemd", ENV{SYSTEMD_WANTS}+="tee-supplicant@%k.service"
>
> So basically dev-tpmrm0.device depends on tee-supplicant at teepriv0.service started
> on dev-teepriv0.device by udev. How to express this dependency?

I am not sure I grok this dependency chain?

What do you mean by ordering the service against dev-tpmrm0.device?
why would you order this? I mean, when
tee-supplicant at teepriv0.service is invoked it will do its thing and
synthesize a /dev/tpmrm0, right?

Generally, you cannot really order device units, it's not under
systemd's unit engine's control when they show up. They show up when
user plugs in a device, or udev triggers a device or the kernel
otherwise probes and makes a device available, and that can be any
time. So we can *wait* for devices, and we can sometimes call tools
that synthesize synthetic devices, but we cannot order arbitrary
devices, that simply is out of our control.

> I tried to queue tee-supplicant at .service with "Wants: tpm2.target" but that did not work
> and seems wrong. The dependency is earlier to the kernel /dev/tpmrm0 device node.
> Then I tried to amend the teepriv udev rule to
> ENV{SYSTEMD_WANTS}+="tee-supplicant@%k.service tpm2.target" and
> ENV{SYSTEMD_BEFORE}+="tpm2.target" but this did not work either. I must be doing this
> somehow wrong. Any ideas what would work?
>
> Example serial log from a rockpi4b board where fTPM is failing to be detected in
> initramfs since tee-supplicant wasn't started:
> https://ledge.validation.linaro.org/scheduler/job/87532

This shows an ordering cycle. Address that first. If you have an
ordering cycle systemd will drop jobs from the initial transactions in
an attempt to fix it, but it's not always clear that the one it drops
it the best one to drop.

The logs do not show that your "tee-supplicant at .service" unit gets
enqueued. So are you sure your udev rule even works?

Lennart

--
Lennart Poettering, Berlin


More information about the systemd-devel mailing list