Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFE: add support for multiple second stage loaders #472

Open
keszybz opened this issue May 5, 2022 · 18 comments
Open

RFE: add support for multiple second stage loaders #472

keszybz opened this issue May 5, 2022 · 18 comments

Comments

@keszybz
Copy link

keszybz commented May 5, 2022

If a distribution wants to support multiple second stage bootloaders, it is hard with the current hardcoded filename (either grub<arch>.efi or the override of DEFAULT_LOADER set at compilation time). Please add support for having multiple second-stage bootloaders installed. The goal is to decouple shim from the second stage bootloader, so that the user can install one or more of the bootloader packages and the new efi binary will be picked up automatically, but at the same time, the bootloader packages don't step on each other's toes and can be updated / installed / removed independently.

I think this could be implemented as a glob or a prefix pattern so it's possible to add new second-stage bootloaders without modifying shim itself. E.g. Fedora could set DEFAULT_LOADERS=fedora-*.efi, and then shim would list all efi binaries present in ESP, and for the ones that match the glob, try them in turn. Or if a glob is too hard to implement, DEFAULT_LOADER_PREFIX=fedora-, and then try to boot anything that starts with the prefix and ends with .efi.

@Conan-Kudo
Copy link

Do we have a restriction to follow DOS 8.3 filenames (since the ESP is a FAT filesystem)?

@keszybz
Copy link
Author

keszybz commented May 5, 2022

In pratice, it's usually VFAT, so there's no issue with long names. FAT12, you'd have 8 characters for the file name. Whoever does the installation and wants to support that would have to shorten the names. Continuing the example above, 'fdra' would be reasonable, leaving 4 characters for the boot loader name.

@julian-klode
Copy link
Collaborator

julian-klode commented May 5, 2022

grub is the only 2nd stage loader that is allowed to be signed with the shim MS trust chain, so it's a bit pointless.

@Conan-Kudo

This comment was marked as off-topic.

@keszybz

This comment was marked as off-topic.

@julian-klode

This comment was marked as off-topic.

@julian-klode
Copy link
Collaborator

julian-klode commented May 5, 2022

One thing that comes to my mind where this is useful though is to provide A/B/... grub updates, such that shim can boot previous grub if new one is broken. But then it also needs to record if an bootloader failed to boot so it skips it next time?

Also we still like need a meta shim or something so that we can fallback to an older shim if a newer one is broken. Though I guess one can always setup the old shim as the fallback loader and have it chainload the new shim (for new keys, etc). And then configure latest shim as boot entry. Needs more thinking about. Well you can't exactly chainload due to breaking TPM measurements.

Also sure, grub is not being signed because it's great code, but for legacy reasons. We're stuck with it :/

@keszybz

This comment was marked as off-topic.

@Conan-Kudo

This comment was marked as off-topic.

@poettering

This comment was marked as off-topic.

@poettering

This comment was marked as off-topic.

@Conan-Kudo

This comment was marked as off-topic.

@julian-klode

This comment was marked as off-topic.

@Conan-Kudo

This comment was marked as off-topic.

@vathpela
Copy link
Contributor

vathpela commented May 6, 2022

Look. We do not need to discuss sd-boot or rEFInd, or what is an application vs a loader vs whatever in this thread. There are plenty of places for those discussions, but this is really not it. If you've got shim-review issues, take them up with reviewers, which you may notice is not attached to this repo.

None of that has any bearing on the feature being requested here, which is fundamentally a request to make shim be able to look for more than one loader, and we can limit our discussions to how to do that and what it would look like. I think it's a valid request, because it's easy for me to see a situation where we might want to load e.g. some test/validation application, and then launch a loader once it has completed, or to do A/B like @julian-klode suggested. But I do have some implementation concerns, which I'll follow up with.

Take anything else to a place more appropriate than shim's issues queue.

@vathpela
Copy link
Contributor

vathpela commented May 6, 2022

Or if a glob is too hard to implement, DEFAULT_LOADER_PREFIX=fedora-, and then try to boot anything that starts with the prefix and ends with .efi.

Either of those is hard to implement for the network boot case, because we can't get directory listings. So probably the thing to do is define it like boot variables, boot${ARCH}####.efi, where #### is four hex characters, and when searching, start at 0000, and iterate 0001, ... 000f, 0010, etc. until we get an EFI_NOT_FOUND.

One thing that comes to my mind where this is useful though is to provide A/B/... grub updates, such that shim can boot previous grub if new one is broken. But then it also needs to record if an bootloader failed to boot so it skips it next time?

How would this wind up working with e.g. luks unlocking with tpm. Since any application we load will get measured, that failure will have a chain of extends with the intermediate failures, and you're not going to get keys unsealed. It seems like we need a reboot in this scenario to keep the measurements from locking us out.

@martinezjavier
Copy link
Contributor

So probably the thing to do is define it like boot variables

I'm worried that using that approach could shorter the EFI storage life expectancy by making too many writes. Another option is just to use a config file in the ESP that contains the current EFI binary and previous one to boot. We could even use a CSV for that to prevent adding yet another parser in shim, since already uses CSV files for the fallback when there's no boot variables.

This wouldn't be less secure since the policy to boot a binary or not should be determined by dbx, SbatLevel, etc so an attacker getting write access to this A/B config file couldn't do more harm than getting write access to EFI variables and adding a fallback BOOTX64.CSV file.

How would this wind up working with e.g. luks unlocking with tpm

I think this is orthogonal to the feature requested here. The system should be designed in a way that the A/B update mechanism and TPM object sealing will work in tandem. This could be achieved for example by using TPM 2.0 Authorized Policies instead of static PCR values when sealing objects, but as said it should be up to the system to make sure that booting a different shim would be safe. This is also true with Secure Boot, updating shim with a version that couldn't be booted would lead to a failure.

@julian-klode
Copy link
Collaborator

julian-klode commented May 9, 2022

I'm worried that using that approach could shorter the EFI storage life expectancy by making too many writes.

@martinezjavier We do not need variables, the proposal from @vathpela was to just name the files in a numbered fashion and try them until we fail to find.

However, this is also problematic in a sense as the range needs to be contiguous. It doesn't have to be for EFI boot variables because there's a BootOrder.

And well I guess one can just write the bootloaders to the boox64.csv. Once fb is integrated, shim should just try all the entries configured there when invoked via removable media path.

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

No branches or pull requests

6 participants