Skip to content

Conversation

@val4oss
Copy link

@val4oss val4oss commented Mar 5, 2024

Goal

The aim of this PR, is to open discussion about the UKI feature for the sdbootutil tool.

Implementation

Corrections

  • The approach may change, as install_uki do things as install_kernel did, a better way would be to create a function install_image called by the two previous functions. What differs from UKI to a Kernel, is that it doesn’t install an initrd (as contained into the efi file) and the content of the entry conf file.

Notes

  • For now there isn’t any interaction with snapshots. I don’t yet get a solution to bring snapshots process with UKI as the CMDLINE is hidden into the binary and cannot be easily changed without break the signature. I am working on at, but the changes could be a good start to add uki entries to bootloader.

Tests

Tested on Tumbleweed booting with sd-boot.

@aplanas
Copy link
Collaborator

aplanas commented Mar 5, 2024

I don’t yet get a solution to bring snapshots process with UKI as the CMDLINE is hidden into the binary and cannot be easily changed without break the signature. I am working on at

IIRC systemd has some proposals for that? I do not remember the details but was something about storing the cmdline as an external file

@val4oss
Copy link
Author

val4oss commented Mar 5, 2024

I don’t yet get a solution to bring snapshots process with UKI as the CMDLINE is hidden into the binary and cannot be easily changed without break the signature. I am working on at

IIRC systemd has some proposals for that? I do not remember the details but was something about storing the cmdline as an external file

Indeed, I can use addons files to override the cmdline.
I didn't explain well my concern, sorry, but the problem is more about the signing process in the distribution provider point of view. If you need to have all files signed during your boot process, each addons (file) that override a section of your efi need to be signed, UKI can be signed by the distribution when the provider gives the image. But snapshots happens in runtime, therefore if you create an addon after the snapshot creation you cannot have a good signature. That why I am searching a way to have multi entries for an UKI according the number of snapshot without using a companion file. But this is maybe for another discussion topic :)

@aplanas
Copy link
Collaborator

aplanas commented Mar 5, 2024

the problem is more about the signing process in the distribution provider point of view

Can the UKI be signed with and empty .cmdline PE section? If that is the case, the cmdline from the addon can be generated locally and delegated to the measure boot process instead of the secure boot one.

That why I am searching a way to have multi entries for an UKI according the number of snapshot without using a companion file.

How can this work? the cmdline requires local information (root UUID, subvol path with the subvol number, etc)

@val4oss
Copy link
Author

val4oss commented Mar 5, 2024

How can this work? the cmdline requires local information (root UUID, subvol path with the subvol number, etc)

root UUID is done by the Discoverable Partitions Specifications, when no CMDLINE has been provided, the tool developed by systemd and present in systemd-stub (stub of the UKI), systemd-gpt-auto-generator, automatically discovers the root partition (https://www.freedesktop.org/software/systemd/man/latest/systemd-gpt-auto-generator.html)

@aplanas
Copy link
Collaborator

aplanas commented Mar 5, 2024

Ah right!

There can be some objections to root uuid auto-discovering in the context of multiple OS installations.

But still curious about the rootflag=subvol= parameter[1], the combination of initrd + kernel is only valid for a subset of snapshots (and is the cmdline the one that links them). Do you think that there is a solution for this too?

[1] https://github.com/openSUSE/sdbootutil/blob/main/ARCHITECTURE.md#introducing-snapshots

@val4oss
Copy link
Author

val4oss commented Mar 5, 2024

Ah right!

There can be some objections to root uuid auto-discovering in the context of multiple OS installations.

Yes you are right, this methods is not adapted for multiple OS, or you should to have as UKI as root fs, but that is not something we may want :)

But still curious about the rootflag=subvol= parameter[1], the combination of initrd + kernel is only valid for a subset of snapshots (and is the cmdline the one that links them). Do you think that there is a solution for this too?

[1] https://github.com/openSUSE/sdbootutil/blob/main/ARCHITECTURE.md#introducing-snapshots

Unfortunately, I do not have any ideas yet about the rootflags parameter.. BTW there is no more combination Kernel+Initrd with the UKI as both are included in the one file. To provide the subvol info, I don't know how the bootloader could pass the information (because the bootloader already know the snapshots number as it is specified into the loader conf file in the Version parameter) to the UKI. I need to study more how snapshots process is done during the boot time

@aplanas
Copy link
Collaborator

aplanas commented Mar 5, 2024

BTW there is no more combination Kernel+Initrd with the UKI as both are included in the one file

Yes sorry. My comment was in the direction that one UKI will be only valid for a subset of snapshots, not for all of them, and we need to map this somehow (currently is done by the cmdline)

the bootloader already know the snapshots number as it is specified into the loader conf file in the Version parameter

Do you mean in the default parameter? I do not see a version parameter in [1]

It is my understanding that when UKIs are used the sd-boot menu entry is autogenerated from the available UKIs, so the mapping issue is still a question for me in the UKI case: how the user can select to boot one UKI in one specific subvolume, and be sure that this selection is valid.

I was expecting that for an UKI solution using snapshots we should need to generate locally the cmdline for an UKI (so we can inspect inside the snapshots the kernels that are valid for it), maybe do some changes in sd-boot to render the combinations of "UKI x addons", and use measured boot instead of secure boot.

I think we should work on a more complete design proposal before evaluating this PR, tho.

[1] https://www.freedesktop.org/software/systemd/man/latest/loader.conf.html

@val4oss
Copy link
Author

val4oss commented Mar 5, 2024

Do you mean in the default parameter? I do not see a version parameter in [1]

I mean Version from the loader conf file: version [email protected]

It is my understanding that when UKIs are used the sd-boot menu entry is autogenerated from the available UKIs, so the mapping issue is still a question for me in the UKI case: how the user can select to boot one UKI in one specific subvolume, and be sure that this selection is valid.

Yes, menu-entries are automatically generated if UKIs are put in esp/EFI/Linux/ folder. But you still can create an entry loader conf file and giving the path to an UKI in esp/loader/entries/my-uki.conf as it done with sdbootuils with the combination of kernel+initrd. So maybe should we manually change this entry loader conf to refer to a Snapshot.

I was expecting that for an UKI solution using snapshots we should need to generate locally the cmdline for an UKI (so we can inspect inside the snapshots the kernels that are valid for it), maybe do some changes in sd-boot to render the combinations of "UKI x addons", and use measured boot instead of secure boot.

I think we should work on a more complete design proposal before evaluating this PR, tho.

I agree with you, I will investigate deeper in UKI solution using snapshots :)

@aplanas
Copy link
Collaborator

aplanas commented Mar 5, 2024

Do you mean in the default parameter? I do not see a version parameter in [1]

I mean Version from the loader conf file: version [email protected]

Ah ... I cannot find it ... neither in the documentation nor in my systemd.

But you still can create an entry loader conf file and giving the path to an UKI in esp/loader/entries/my-uki.conf

Indeed ... like a chain load. I like this idea.

@lnussel
Copy link
Member

lnussel commented Mar 6, 2024

In general I'm ok with adding uki support to sdbootutil. We need to avoid the code duplication with install_kernel() though.
In theory the snapshot to boot could be extracted from the selected boot entry for a start. It's stored in the 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f-LoaderEntrySelected efi variable. So the initrd could parse it. Not the most elegant solution but could get us started.
There was some discussion or pr somewhere about adding wildcard matching to kernel command lines for uki. I think it stalled and I can't find it right now though :/ that could also help us with the snapshot passing.

@val4oss
Copy link
Author

val4oss commented Mar 6, 2024

In theory the snapshot to boot could be extracted from the selected boot entry for a start. It's stored in the 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f-LoaderEntrySelected efi variable. So the initrd could parse it. Not the most elegant solution but could get us started.

Could be good to give a try for a first start yes.

There was some discussion or pr somewhere about adding wildcard matching to kernel command lines for uki. I think it stalled and I can't find it right now though :/ that could also help us with the snapshot passing.

I found this discussion from systemd project, and talk about snapshots begins here : systemd/systemd#24539 (comment) maybe it is the PR you refereed for ?

@lnussel
Copy link
Member

lnussel commented Mar 26, 2024

missed the question part. yes that is the discussion

- add 'add-uki' and 'remove-uki' command to add or remove an entries
  using UKI.

Signed-off-by: Valentin Lefebvre <[email protected]>
reset_rollback
# This action will require to update the PCR predictions
update_predictions=1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way to calculate predictions will change too, right?

{
local subvol="$1"
local kernel_version="$2" # Same as kernel version
if [ "$image" = "vmlinuz" ] || [ "$image" = "Image" ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mixing tabs and spaces, I added .dir-locals.el for emacs, but you can add another for your editor. I used the one from systemd as an example

fi
calc_chksum "$src"
local dst="/$entry_token/$kernel_version/uki-$chksum"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the hash is to reuse kernel and initrds, do you think that this will be useful for ukis too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure yet but probably not. There is a concept with "extensions", others efi binaries that can be load with the UKI to extend his initrd. In that way, we will have the same structur of kernel+initrd, so the hash could be useful in that case. I need to think about that

snapshot="${snapshot%/*}"
local id="$entry_token-uki-$kernel_version-$snapshot.conf"
run_command_output bootctl unlink "$id"
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is mostly the same code than remove_kernel (missing the prediction stuff), so I am wondering if would make sense to unify {add,remove}_kernel with {add,remove}_uki.

I am not sure that makes total sense, tho.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It clearly makes sense to merge $command_kernel with $command_uki, and maybe rename the functions into $command_image.
First goal was to introduce the uki process, that why I split it in these new functions

sdbootutil Outdated
aa64) image=Image ;;
*) err "Unsupported architecture $firmware_arch" ;;
esac
if [ -z "$image" ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwanted sorry

@TobiPeterG
Copy link
Collaborator

A UKI can now contain multiple profiles, allowing to configure multiple, separate command lines.
This could be used, also shown in the linked discussion :)

@val4oss
Copy link
Author

val4oss commented Feb 12, 2025

A UKI can now contain multiple profiles, allowing to configure multiple, separate command lines. This could be used, also shown in the linked discussion :)

Profile feature is great to have multiple entries for the same UKI but with different command line. However, if I well understand profiles, these sections need to be included into the efi binary, for each new snapshot created, a called to ukify is needed and the efi binary will be regenerated, where in the vendor POV we signed the binary, it is not feasible.

However, as you suggested into the linked discussion, a multi-profiles with addons would works for snapshots. It will be closed of what I am testing with UKI and snapshots. I have wrote a short documentation on it : https://github.com/keentux/unified-kernel-image-tool/blob/main/docs/unified-kernel-image.md#v---snapshots

@TobiPeterG
Copy link
Collaborator

@keentux
Hey, as part of a University course I will work on UKIs on openSUSE. What is the current state? I saw that there already is a uki package in Factory. :)

@val4oss
Copy link
Author

val4oss commented May 12, 2025

Hi @TobiPeterG , Happy to see there are some interests of UKIs on openSUSE. :)

Indeed, there are some packages in Factory, available for Tumbleweed:

  1. uki-tool: a tool to regroup useful commands dealing with the UKI and adapted for the packaging.
    Sources: https://github.com/keentux/unified-kernel-image-tool
  2. static-initrd-generic-unsigned: provides Unsigned static initrd. (Package name may move for next update to include kernel flavors used)
  3. uki-$kernelflavor: provides Signed Unified Kernel Images. based on the kernel flavor (for now, only the default flavor is provided, will comme soon, the vanilla flavor) and based on the unsigned static initrd.

When installing the uki package it will automatically add a bootloader entry depending if you used grub2 or sdboot. I will recommend to not install yet the uki as I am working of an update that will improve the way bootloader entries are created. It is done by the uki-tool and the release should start asap.

You can find more documentation about static-initrd and uki here: https://en.opensuse.org/SDB:Static_Initrd_and_Unified_Kernel_Image
And finally, I made a short presentation last year (a bit old therefor) where the replay can be found here: https://www.youtube.com/watch?v=w1nMenPL1Uw

About this PullRequest status: I am working on the PR on systemd which I based my POC on to manage snapshots in openSUSE with the UKI, because with the new systemd version, my POC is broken and requires some changes.

I hope this provides some insight into the status of the UKI. Please feel free to contact me if you need any information or assistance. 😁

@TobiPeterG
Copy link
Collaborator

TobiPeterG commented May 19, 2025

Hi @TobiPeterG , Happy to see there are some interests of UKIs on openSUSE. :)

Indeed, there are some packages in Factory, available for Tumbleweed:

  1. uki-tool: a tool to regroup useful commands dealing with the UKI and adapted for the packaging.
    Sources: https://github.com/keentux/unified-kernel-image-tool
  2. static-initrd-generic-unsigned: provides Unsigned static initrd. (Package name may move for next update to include kernel flavors used)
  3. uki-$kernelflavor: provides Signed Unified Kernel Images. based on the kernel flavor (for now, only the default flavor is provided, will comme soon, the vanilla flavor) and based on the unsigned static initrd.

When installing the uki package it will automatically add a bootloader entry depending if you used grub2 or sdboot. I will recommend to not install yet the uki as I am working of an update that will improve the way bootloader entries are created. It is done by the uki-tool and the release should start asap.

You can find more documentation about static-initrd and uki here: https://en.opensuse.org/SDB:Static_Initrd_and_Unified_Kernel_Image And finally, I made a short presentation last year (a bit old therefor) where the replay can be found here: https://www.youtube.com/watch?v=w1nMenPL1Uw

About this PullRequest status: I am working on the PR on systemd which I based my POC on to manage snapshots in openSUSE with the UKI, because with the new systemd version, my POC is broken and requires some changes.

I hope this provides some insight into the status of the UKI. Please feel free to contact me if you need any information or assistance. 😁

Thank you very much for this detailed report. :)
Can you link the systemd PR please? I had a look at
systemd/systemd@main...keentux:systemd:addon-stanza-type1
Do you mean this branch? This would add a property to type 1 boot entries to select what addons should be loaded, right? I'm not sure if Lennard will like this approach, he's a fan of having these things automated.
I guess it would be logical (and great to automate) if you could only select addons when they override a property set in the UKI or two addons want to set the same property. This way there is no need to extend type 1 entries. :)
(I could also work on that if you want to)

I would love to help with snapshot support. If you don't want/need help on that side for now, I would also love to work on the initrd and signing side. We need a way to add the modules the user wants/needs as addons to the base initrd. Do you know if dracut supports creating the addons?
I guess sdbootutil also needs support
As for signing: I guess it should be possible to sign the addons locally uisng MOK to be able to boot them, right? Is that already supported?
Is there any other area you want/need support in? :)

@val4oss
Copy link
Author

val4oss commented May 26, 2025

Can you link the systemd PR please? I had a look at systemd/[email protected]:systemd:addon-stanza-type1 Do you mean this branch? This would add a property to type 1 boot entries to select what addons should be loaded, right? I'm not sure if Lennard will like this approach, he's a fan of having these things automated. I guess it would be logical (and great to automate) if you could only select addons when they override a property set in the UKI or two addons want to set the same property. This way there is no need to extend type 1 entries. :) (I could also work on that if you want to)

Yes, it is the PR I refereed,I will soon create a new one which is based on the latest systemd commits, that's why I didn't mention it ;)

I would love to help with snapshot support.

Your help would be greatly appreciated, thank you very much for your offer. In order not to burden this discussion with sdbootutil, I created a thread here: val4oss/unified-kernel-image-tool#1
to be able to talk about it more simply, and this also allows me to explain the why and how of the work in progress. Would it be okay for you to exchange together in this thread?

I would also love to work on the initrd and signing side. We need a way to add the modules the user wants/needs as addons to the base initrd.

I also created another thread for you that explains how the signing process is done for ukis/initrd/uki-companions
val4oss/unified-kernel-image-tool#2 I will also report your question on it to answer there :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants