Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Trying to use UKIs: Error because of composefs= parameter mismatch #1984

Answered by Johan-Liebert1
marcoh00 asked this question in Q&A
Discussion options

Hi there!

I've been playing around with UKIs and wanted to see whether I could get Secure Boot to work in combination with an Arch Linux base image. For this, I mainly replicated the instructions from the docs, which seem to be very similar to the steps in the Dockerfile at the root of the bootc repository. As such, this is what I came up with:

FROM ghcr.io/bootcrew/arch-bootc:latest AS rootfs
RUN --mount=type=secret,id=secureboot_key \
 --mount=type=secret,id=secureboot_cert <<EORUN
set -euxo pipefail
# Make sure locales and man pages are not ignored and install basic packages
sed -i 's/NoExtract /# NoExtract /g' /etc/pacman.conf
# For testing: Just install the SB-related utilities here so we can use this image
# both as the "base" and as the "tools" image.
pacman -Sy
pacman -S --noconfirm glibc glibc-locales efitools efibootmgr mokutil sbsigntools systemd-ukify
# Sign systemd-boot EFI binaries
# bootctl will detect the .signed binaries and prefer them over the unsigned ones
sbsign \
 --key /run/secrets/secureboot_key \
 --cert /run/secrets/secureboot_cert \
 --output "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed" \
 "/usr/lib/systemd/boot/efi/systemd-bootx64.efi"
sbverify \
 --cert /run/secrets/secureboot_cert \
 "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed"
# In case this ever actually installs and boots up, set a root password to be able to look around a bit...
echo 'root:password' | chpasswd -c YESCRYPT
EORUN
FROM rootfs as sealed-uki
RUN --mount=type=bind,from=rootfs,target=/target,ro \
 --mount=type=secret,id=secureboot_key \
 --mount=type=secret,id=secureboot_cert <<EORUN
set -euxo pipefail
# `bootc container compute-composefs-digest` creates a temporary composefs repo in /var/tmp, which doesnt exist inside the base image
mkdir -p /var/tmp
# Compute the composefs digest from the mounted rootfs
digest=$(bootc container compute-composefs-digest /target)
# Find the kernel version
kver=$(basename $(find /usr/lib/modules -maxdepth 1 -mindepth 1 -type d -print0))
mkdir /out
# From the docs. Fails with:
# > error: Installing to disk: Setting up composefs boot: Setting up UKI boot: Writing 6.18.7-arch1-1.efi to ESP: The UKI has the wrong composefs= parameter (is 'sha512:0cc1...', should be sha512:fdca...)
# Generate and sign the UKI with the digest embedded
# ukify build \
# --linux "/target/usr/lib/modules/${kver}/vmlinuz" \
# --initrd "/target/usr/lib/modules/${kver}/initramfs.img" \
# --cmdline "composefs=${digest} rw" \
# --os-release "@/target/usr/lib/os-release" \
# --signtool sbsign \
# --secureboot-private-key /run/secrets/secureboot_key \
# --secureboot-certificate /run/secrets/secureboot_cert \
# --output "/out/${kver}.efi"
# From the `seal-uki` script:
bootc container ukify --rootfs "/target" \
 --karg enforcing=0 \
 -- \
 --signtool sbsign \
 --secureboot-private-key "/run/secrets/secureboot_key" \
 --secureboot-certificate "/run/secrets/secureboot_cert" \
 --measure \
 --json pretty \
 --output "/out/${kver}.efi"
EORUN
FROM rootfs
COPY --from=sealed-uki /out/*.efi /boot/EFI/Linux/

This is the error I get when I try to install this image via bootc install to-disk:

error: Installing to disk: Setting up composefs boot: Setting up UKI boot: Writing 6.18.7-arch1-1.efi to ESP: The UKI has the wrong composefs= parameter (is 'sha512:bf864670d49635894050223df34d96ca5c8840f9acd6d6a8cf3090b31987bc9173b64d6be2d8fa49a2e684af4abcb7eaed6c15af2cd769d39109af826851010e', should be sha512:d533564f412fb87ae249d526ce8d968613b74561e7bdd13e34017e8967dc1b5af7116bc8973f46f496bc27d6d4008a4315b7ac9890f68b0b64ef3af547d27969)

I guess it makes sense: The about-to-be-installed image includes the UKI, while the rootfs - the image composefs digest was calculated of - does not. So different checksums are expected here.

I had a look at the source code and noticed that create_composefs_filesystem - where the "expected" composefs digest comes from, does not special-case files in /boot (which - again - makes sense), so naturally these files become a part of the digest.

So my question is: How is this meant to be used? I would have expected that either bootc takes care of not including the files in /boot in the checksum calculation or that I'm able to specify an UKI to be installed on top of the rootfs image, such that the situation where I'd need to include a signed digest into an image - and thus changing this exact digest - doesn't happen. What am I missing?

You must be logged in to vote

This seems like an issue with our xattr filters that we only apply on one path. Ref composefs/composefs-rs#211 (comment), composefs/composefs-rs#212

Replies: 3 comments 3 replies

Comment options

When this is has happened to me in the past I diffed the computed filesystem trees - use --write-dumpfile-to.

Actually see

fn validate_composefs_digest(sh: &Shell, args: &ValidateComposefsDigestArgs) -> Result<()> {
which we could probably just break out into a helper utility.
You must be logged in to vote
0 replies
Comment options

Can you check if you got bit by e.g. composefs/composefs-rs#211 (comment)

You must be logged in to vote
0 replies
Comment options

Hey, thanks for these suggestions!

I have a dumpfile now, so I know what bootc container compute-composefs-digest sees. Unfortunately, I can't spot anything unusual in there. It would be helpful to have another dumpfile of what bootc install sees and why it differs.

What I tried is to call the bootc binary from my host like this:

bootc container compute-composefs-digest-from-storage --write-dumpfile-to from-outside.dump 1a453cb05673

where 1a453cb05673 is the image id podman wrote to stdout after building rootfs. Is this a sensible approach?

Anyways, those are quite different from each other. It starts with different permissions for / (40555 vs. 40755) and goes on with a few files from /etc seemingly having an user.overlay.origin=- xattr set (??) when looking at the image "from the outside", but apparently not inside the build context.

It doesn't seem about SELinux labels (none of the files have them and the Arch Linux images don't include anything SELinux related, including any policy) and neither about the random-seed (which doesn't even exist in the image)

You must be logged in to vote
3 replies
Comment options

Had another look at this and it's definitely the xattrs. I ended up calling compute-composefs-digest-from-storage just like I'd called install to-disk (plus mounting /run/host-container-storage) and I guess this is the correct way.

$ diff -N from-outside.dump from-build.dumpfile 
6c6
< /etc/.pwd.lock 0 100600 1 0 0 0 1771146228.0 - - - user.overlay.origin=-
---
> /etc/.pwd.lock 0 100600 1 0 0 0 1771146228.0 - - -
13c13
< /etc/audit 0 40755 4 0 0 0 1771151547.0 - - - user.overlay.origin=-
---
> /etc/audit 0 40755 4 0 0 0 1771151547.0 - - -
497c497
< /etc/default 0 40755 2 0 0 0 1761374527.0 - - - user.overlay.origin=-
---
> /etc/default 0 40755 2 0 0 0 1761374527.0 - - -
560,561c560,561
< /etc/pacman.d 0 40755 3 0 0 0 1771146222.0 - - - user.overlay.impure=y user.overlay.origin=-
< /etc/pacman.d/gnupg 0 40755 4 0 0 0 1771146228.0 - - - user.overlay.impure=y user.overlay.origin=-
---
> /etc/pacman.d 0 40755 3 0 0 0 1771146222.0 - - -
> /etc/pacman.d/gnupg 0 40755 4 0 0 0 1771146228.0 - - -
570c570
< /etc/pacman.d/gnupg/trustdb.gpg 12960 100644 1 0 0 0 1771146228.0 b1/52124436e928dff19059b64c2b04cef8e74d9ee9a7c77a64b5dc0a3edfa19143226a7ab47c6f152503839be601bf04873bfc75d8d9cf17a19de47c46d7623d - b152124436e928dff19059b64c2b04cef8e74d9ee9a7c77a64b5dc0a3edfa19143226a7ab47c6f152503839be601bf04873bfc75d8d9cf17a19de47c46d7623d user.overlay.origin=-
---
> /etc/pacman.d/gnupg/trustdb.gpg 12960 100644 1 0 0 0 1771146228.0 b1/52124436e928dff19059b64c2b04cef8e74d9ee9a7c77a64b5dc0a3edfa19143226a7ab47c6f152503839be601bf04873bfc75d8d9cf17a19de47c46d7623d - b152124436e928dff19059b64c2b04cef8e74d9ee9a7c77a64b5dc0a3edfa19143226a7ab47c6f152503839be601bf04873bfc75d8d9cf17a19de47c46d7623d
572c572
< /etc/pam.d 0 40755 2 0 0 0 1771151544.0 - - - user.overlay.origin=-
---
> /etc/pam.d 0 40755 2 0 0 0 1771151544.0 - - -
597c597
< /etc/profile.d 0 40755 2 0 0 0 1771152232.0 - - - user.overlay.origin=-
---
> /etc/profile.d 0 40755 2 0 0 0 1771152232.0 - - -
2746,2747c2746,2747
< /usr/include/dbus-1.0 0 40755 3 0 0 0 1759128552.0 - - - user.overlay.impure=y user.overlay.origin=-
< /usr/include/dbus-1.0/dbus 0 40755 2 0 0 0 1759128552.0 - - - user.overlay.origin=-
---
> /usr/include/dbus-1.0 0 40755 3 0 0 0 1759128552.0 - - -
> /usr/include/dbus-1.0/dbus 0 40755 2 0 0 0 1759128552.0 - - -
[ + quite a few more]

I did solve the permissions for root by introducing a chunkah step. While this is probably not universally good advice it's what I wanted to do anyway, so... I'm glad it works 🤷‍♂️

Now I'm afraid I'll have to take a close look at how the base image is built exactly and where those xattrs are coming from. As the bootcrew CI uses the buildah action this probably the main suspect here...

Comment options

This seems like an issue with our xattr filters that we only apply on one path. Ref composefs/composefs-rs#211 (comment), composefs/composefs-rs#212

Answer selected by marcoh00
Comment options

It took a while, but I think I understand now :-) Thanks for the pointers! Guess we'll have to wait for a fix then.

Btw, in case anyone stumbles over this and has the same issue: It works for me if I build the container starting from the Arch Linux image locally, i.e. include the Containerfile from bootcrew/arch-bootc as the first stage and build from that. I'm currently on podman 5.7.1/buildah 1.42.2 if it matters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /