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

Enhancement: fail boot if users expect SecureBoot and there's an issue with certificates #16

Open
stormi opened this issue Oct 26, 2022 · 6 comments

Comments

@stormi
Copy link
Contributor

stormi commented Oct 26, 2022

A difference between uefistored and varstored was a change we made on purpose to avoid giving users a false sense of security.

If varstored is told to enforce SecureBoot, it will silently decide not to enforce it if there's any issue with the certificates in the VM's NVRAM. Missing certificates, broken chain of trust...

Example as seen in daemon.log. Nothing tells that secure boot was actually disabled at the last minute:

Oct 26 16:59:28 r620-x2 varstored-132[9782]: varstored_initialize: 1 vCPU(s)
Oct 26 16:59:28 r620-x2 varstored-132[9782]: varstored_initialize: ioservid = 0
Oct 26 16:59:28 r620-x2 varstored-132[9782]: varstored_initialize: iopage = 0x7f6bc35b4000
Oct 26 16:59:28 r620-x2 varstored-132[9782]: varstored_initialize: VCPU0: 4 -> 194
Oct 26 16:59:28 r620-x2 varstored-132[9782]: initialize_settings: Secure boot enable: true
Oct 26 16:59:28 r620-x2 varstored-132[9782]: initialize_settings: Authenticated variables: enforcing
Oct 26 16:59:28 r620-x2 varstored-132[9782]: IO request not ready

It may be consistent with the UEFI specifications, and may make sense for hardware. But in the context of a hypervisor, for users who probably don't understand how exactly the certificates are handled and how all this works, this is confusing: they ask for SecureBoot and the VM boots, so the logical assumption is: nothing went wrong and SecureBoot is enforced. The only way to be sure that it's true is by checking from within the VM.

In uefistored, without a proper means to give feedback to XAPI, we simply made uefistored kill itself with an error log, after sending a VM_SECURE_BOOT_FAILED message to XAPI. It's not perfect, but at least a VM with missing or broken certificates would not boot if users asked for SecureBoot and we can't give it to them. It's not exactly a SecureBoot failure, but it was close enough for us to reuse the VM_SECURE_BOOT_FAILED. We could also have created a different error but it would have been hard to contribute to XAPI at the time.

Could we improve this in varstored and/or XAPI?

  • Simple case: missing certs (PK, KEK or db. dbx is optional): this could be detected by XAPI directly before even starting the VM
  • More complex case: certs are present but there's an issue with them. Malformed, not signed properly or not with the right keys, etc. A first sight, looks like something varstored already checks and could act upon. The minimum would be to log an error, useful for anyone checking the logs but not enough to give the right feedback to users. The ugly way would be simply killing itself with a meaningful error message. A probably better way would be communicating back with XAPI to let it know there's a problem, and abort the boot process.

We can certainly contribute the changes if we agree on a design.

@rosslagerwall
Copy link
Collaborator

The goal for OVMF + varstored as implemented in XenServer is to provide a standards-compliant implementation of UEFI. This means that a VM owner is free to set their own variables, PK, KEK, etc. and also means that a VM may go from User mode to Setup mode at any time with consqeuent clearing of the SecureBoot variable. I wouldn't plan on making any changes that breaks this, at least in the default configuration.

The semantics when setting a VM's platform/secureboot=1 means 'enable Secure Boot when the platform is in User mode (i.e. SetupMode == 0)' and to that end it behaves as expected.

Having said that, I think it would be acceptable to add an optional flag to varstored such that it would generate a new XAPI notification and/or abort if SecureBootEnable=1 and SecureBoot=0 at startup time. In either case it would be fine to log the state of variables at the end of setup_keys().

On a side note, you can't reliably tell whether Secure Boot is enabled from within the guest OS since if Secure Boot is not enabled, the attacker can replace the OS kernel with one which always reports that Secure Boot is enabled. This doesn't apply to the guest firmware which cannot be controlled by the attacker in the threat models that Secure Boot protects against.

@stormi
Copy link
Contributor Author

stormi commented Oct 26, 2022

Oh. Is there a reliable way to tell whether Secure Boot is enabled, in the current state of varstored and XAPI? I remember having looked at the EFI variables in the NVRAM but IIRC they were not always up to date when seen from the host.

@stormi
Copy link
Contributor Author

stormi commented Nov 30, 2022

Oh. Is there a reliable way to tell whether Secure Boot is enabled, in the current state of varstored and XAPI? I remember having looked at the EFI variables in the NVRAM but IIRC they were not always up to date when seen from the host.

I would be interested in displaying a reliable Secure Boot status in Xen Orchestra. Is there a way? If not, what would be required to let XAPI get and then offer this piece of information?

@andSmv
Copy link

andSmv commented Aug 23, 2023

Hello Ross,

With regard of "optional flag" to abort guest boot, I actually made a reference to a XenStore variable. In my opinion, this is more in line with how Varstored should figure these kinds of things out.
We tried to push some changes to the XAPI (to actually implement this XenStore variable), and the XAPI maintainers suggested that we would be better off specifying this behaviour (guest abort) as a Varstored command line option.

What do you think would be an acceptable solution to this problem?

@stormi
Copy link
Contributor Author

stormi commented Sep 6, 2023

So, regarding all this, there was a misconception on my side regarding how varstored works.

In short: the security problem I was trying to get solved doesn't exist.

There is a difference between setup mode (no PK) and user mode with no certs but PK.

IIRC, in early versions of uefistored, that apparently didn't behave on this point like varstored, Secure Boot would get silently disabled if PK is present but other certs are absent or can't be verified, despite SecureBootEnable=1. I thought this was going per the UEFI spec (I didn't check it myself, I just relied on what the dev told me), but I wanted to avoid users thinking they enabled SecureBoot when in fact they didn't, to avoid a false sense of security. So we made uefistored kill itself in this situation, to prevent the VM from booting.

A UEFI VM with only PK in its certs can be commonly found. It's sufficient that is was booted on XCP-ng 8.2 without users having run secureboot-certs install on the pool before, or on a Non-UEFI Citrix Hypervisor 8.2 pool (AFAICT). I thought such VMs would boot even if users enabled Secure Boot in XAPI, but with Secure Boot actually disabled in the VM. That's why I treated it as a security issue and wanted to prevent it. But the behaviour I feared can only happen if the VM is in setup mode (no PK), not user mode, and a UEFI VM with no PK, as far as I can tell, is not supposed to exist unless the user purposefully switched to setup mode. In user mode with no certs but PK, a VM with SecureBootEnable=1 will not boot and will enter UEFI shell instead. Which is not perfect from a usability standpoint, but is not a security problem.

Closing this enhancement request.

@stormi stormi closed this as completed Sep 6, 2023
@stormi stormi reopened this Mar 22, 2024
@stormi
Copy link
Contributor Author

stormi commented Mar 22, 2024

Reopening.

I missed a key point: when your pool doesn't have any certificates other than PK, there is code in varstored to prevent setup_keys from completing, to workaround the bug where Windows sees it is in user mode and isn't able to update dbx due to lack of KEK/db.

Consequence: any newly created VM ends up in setup mode, and users wrongly believe that Secure Boot is enforced . We had proof of this in a youtube video from a skilled youtuber who knows XCP-ng very well, tests beta releases, etc.

So there is a security issue here in XCP-ng's case where we don't distribute Microsoft's certs due to their license having restrictions which are incompatible with Free Software.

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

3 participants