[systemd-devel] Measured systemd-sysext
Lennart Poettering
lennart at poettering.net
Fri May 24 15:44:55 UTC 2024
On Fr, 24.05.24 17:39, Dimitris Karakasilis (dimitris at karakasilis.me) wrote:
> we (at kairos.io) are trying to understand how systemd-sysext
> extensions can
Hmm, I thought kairos wasn't so fond of systemd?
> also be made tamper-proof by being measured in a system that boots in UKI
> mode.
It's pretty simple: there's no nice support for comprehensively
measuring sysext images right now. There's support for measuring into
PCR 13 the sysext images passed into the UKI, but that's pretty much
it: there's no support for measuring sysexts activated from other
sources and later during runtime.
So there are two issues:
1. Right now we don't really have another PCR to spare. The various
PCRs systemd measures stuff into right now contain maesurements
that typically happen only once during boot. That makes them really
nice for validating/attesting boot success, or to bind policy to
and so on, as they are relatively stable, they "settle"
eventually. Measurements of sysexts on activation are different
from that, after all sysexts are added/removed/updated during
runtime all the time, hence they probably should be expected to be
a continuing series of measurements, one for each activation during
runtime. That makes them nice for attestation, but much less useful
for binding policy to. Hence, I think there's a strong reason to
keeping these measurements separate from the existing measurements,
i.e. place them in a separate PCR – but we have none left.
Now, TPM2 allows adding new "fake" PCRs via a special type of
nvindex so that this restriction goes away. It's high on our todo
list to have an API for "registering" such "fake" PCRs (which would
mean: allocating the nvindex with an apprpriate locked down policy,
and then storing information about this somewhere). This should
probably be placed in systemd-pcrextend at .service (which already
provides an API to measure arbitrary stuff to arbitrary PCRs, so it
looks like it would be a nice place to allow measuring arbitrary
stuff to "fake" PCRs, and allocating them. This is probably not
particularly involved, but so far noone has worked ont his.
2. The questions is where (in which piece of code) the system
extensions should be measured. There are two potential places: when
we activate them, from userspace code. That would be trivial to add for
us. We have all the internal apis after all. i.e. we could just use
the aforementioned pcrextend apis once we have them to allocate a
fake PCR and then immediately measure into them.
However, what might be nicer would be to measure this in kernel
space. I was discussing this at last week's LSFMMBPF conference
with various relevant folks, and one idea we came up with is
something like this:
a) introduce a BPF kfunc for TPM measurements in the kernel, so
that BPF code loaded into the kernel can do measurements. THis
would require an upstream kernel patch, but the BPF folks seemed
kinda on board with that.
b) then put together a small BPF LSM for the Linux kernel that
hooks into the dm-verity activation, and does two things:
measures the root hash of the device (plus some metadata such as
the DM device name), and writes a quick log message into a bpf
ringbuffer to userspace. Userspace would then read that and
ensure the log ends up in the measurement logs systemd maintains
anyway.
In systemd we already ship and load some BPF LSMs, adding another
like the above should be relatively straight-forward.
(Of course, it's a bit more complicated than this, because a BPF
kfunc that can measure into a PCR is not going to be enough [NB:
the kernel already has general code to measure into PCRs], after
all we want to measure into a "fake PCR" nvindex, which the kernel
has no existing code for yet. Somebody would have to write that
first, but it should be managable).
Putting this all together (under the assumption we go for the bpf-lsm
option), the codeflow would be something like this:
1. early during boot, systemd allocates a "fake PCR" for dm-verity
measurements, from userspace
2. it then loads the small BPF LSM that makes sure all dm-verity
activations are measured, and parameterizes it with the allocated
fake PCR nvindex.
3. A bpf ringbuffer is kept in place that will receive the measurement
log from the bpf lsm, and some code in userspace picks the data up
from there and writes it to the usual measurement log.
And then we should have a really nice, very comprehensive solution.
Work to making this a reality would be very welcome of course.
(Full disclosure: you can use IMA today to measure all dm-verity root
hashes into the IMA logs, but I personally am not a fan of IMA, it's a
complex beast with so many features I find quite questionnable today,
that I'd rather have a much much simpler lsm-bpf as alternative, that
just does this one thing and nothing else. IMA keeps its logs in
kernel memory, unbounded, with no mechanism for rotation, which I
personally find a complete dealbreaker.)
So much about my current ideas regarding all this.
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list