rhboot / shim

UEFI shim loader
Other
816 stars 284 forks source link

Too big `dbx` causes Shim to refuse to boot, presumably due to "failure" from `tpm2->hash_log_extend_event()` #654

Open peat-psuwit opened 2 months ago

peat-psuwit commented 2 months ago

On my ASUS Transformer Mini T103HAF [1], applying a too big dbx update from e.g. Ubuntu 24.04 beta live CD can cause Shim to refuse too boot, citing "Volume Full" despite plenty of space reported from efivars filesystem on Linux. Upon further investigation, this "Volume Full" error probably comes from tpm2->hash_log_extend_event(), as I'll demonstrate below.

Step to reproduce:

  1. Download & flash Ubuntu 24.04 beta live CD to a USB drive [2]. This image contains Shim 15.8-0ubuntu1 and a secureboot-db which "Update dbx to 2023-05-09 release".
  2. Boot this image on the tablet. Upon boot, verify that efivars isn't close to full.
    $ df -h /sys/firmware/efi/efivars
    Filesystem Size Used Avail Use% Mounted on
    efivarfs 128K 67K 57K 55% /sys/firmware/efi/efivars
  3. Now reboot into the same boot image again. This time, Shim will refuse to boot, citing the following:
    Could not create MokListRT: Volume full
    Could not create MokListXRT: Volume full
    Could not create SbatlevelRT: Volume full
    Could not create MokListTrustedRT: Volume full
    Something has gone seriously wrong: import_mok_state() failed : Volume Full

    But we've just established that efivars isn't even close to full. So what gives?

  4. Now disable Secure Boot, modify the boot image on the USB drive so that it boots Grub directly instead, and boot the image again. After that, enable Shim verbose mode by running sudo mokutil --set-verbosity true.
  5. Modify the boot image again so that it will load Shim. Boots off that. This time, you'll find the log that says:
    mok.c:798:mirror_one_mok_variable() tpm_log_event(0x73207F18, 76, 14, "MokListX")->Volume Full
    Could not create MokListXRT: Volume Full
    mok.c:926:import_one_mok_state() returning Volume Full

Or:

mok.c:762:mirror_one_mok_variable() tpm_measure_variable("SbatLevel",46,0x73207F98)->Volume Full
Could not create SbatLevelRT: Volume Full
mok.c:926:import_one_mok_state() returning Volume Full

The full log is available in the picture form at [3] (since I don't know how to collect the log otherwise).

Here comes my analysis: both tpm_measure_variable() and tpm_log_event() calls tpm_log_event_raw() which in turns call tpm2->hash_log_extend_event(). Now, the TCG EFI Protocol Specification family 2.0 [4] section 6.6.6 specifies EFI_VOLUME_FULL as one of the possible error of EFI_TCG2_PROTOCOL.HashLogExtendEvent, describing it as "The extend operation occurred, but the event could not be written to one or more event logs". So, what I assume happens is that the full content of dbx are included into this event log, which consumes so much space it can't log any other variable, hence EFI_VOLUME_FULL "failure".

Now, the reason I put "failure" in quote is because 1.) the extend operation still occurs, and 2.) go-attestation mentions in one of their vulnerability disclosure [5] that "The TCG noted that event data is meant for debugging". So, I think this error from tpm2->hash_log_extend_event() could be considered non-fatal?

Note that before I come to this conclusion, I've reported this issue to Ubuntu before as [6].

[1] Additional information about my device: Make & model: ASUS Transformer Mini T103HAF Firmware (BIOS) make & version: American Megatrends Inc. T103HAF.309, 22/4/2019 TPM manufacturer: INTC TPM manufacturer version: 2.0.5.3015 TPM specification version: 2.0

[2] https://releases.ubuntu.com/noble/ubuntu-24.04-beta-desktop-amd64.iso [3] https://ibb.co/album/RzXY28 (sorry for low quality. And note that this is actually collected from Fedora 39 KDE spin live image, which seems to include Shim 5.16.) [4] https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf [5] https://github.com/google/go-attestation/blob/master/docs/event-log-disclosure.md#vulnerability-report-and-outcome [6] https://bugs.launchpad.net/ubuntu/+source/secureboot-db/+bug/2061551

vathpela commented 2 months ago

I think the thing to do here is:

1) make errors from the log events - and only the log events - display the failure but not be fatal. 2) keep our own log and publish it in the mok variables configuration table