[PATCH] efi_loader: Increase default variable store size to 32K

Debian's arm64 UEFI Secure Boot shim makes the EFI variable store run out of space while mirroring its MOK database to variables. This can be observed in QEMU like so:
$ tools/buildman/buildman -o build/qemu_arm64 --boards=qemu_arm64 -w $ cd build/qemu_arm64 $ curl -L -o debian.iso \ https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-12.0.0-arm6... $ qemu-system-aarch64 \ -nographic -bios u-boot.bin \ -machine virt -cpu cortex-a53 -m 1G -smp 2 \ -drive if=virtio,file=debian.iso,index=0,format=raw,readonly=on,media=cdrom [...] => # interrupt autoboot => env set -e -bs -nv -rt -guid 605dab50-e046-4300-abb6-3dd810dd8b23 SHIM_VERBOSE 1 => boot [...] mok.c:296:mirror_one_esl() SetVariable("MokListXRT43", ... varsz=0x4C) = Out of Resources mok.c:452:mirror_mok_db() esd:0x7DB92D20 adj:0x30 Failed to set MokListXRT: Out of Resources mok.c:767:mirror_one_mok_variable() mirror_mok_db("MokListXRT", datasz=17328) returned Out of Resources mok.c:812:mirror_one_mok_variable() returning Out of Resources Could not create MokListXRT: Out of Resources [...] Welcome to GRUB!
This would normally be fine as shim would continue to run grubaa64.efi, but shim's error handling code for this case has a bug [1] that causes a synchronous abort on at least chromebook_kevin (but apparently not on QEMU arm64).
Double the default variable store size so the variables fit. There is a note about this value matching PcdFlashNvStorageVariableSize when EFI_MM_COMM_TEE is enabled, so keep the old default in that case.
[1] https://github.com/rhboot/shim/pull/577
Signed-off-by: Alper Nebi Yasak alpernebiyasak@gmail.com --- I'm not very familiar with EFI things, apologies if this default should not be changed (consider this a bug report in that case).
lib/efi_loader/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c5835e6ef61a..0660d1174902 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -96,7 +96,8 @@ endif
config EFI_VAR_BUF_SIZE int "Memory size of the UEFI variable store" - default 16384 + default 16384 if EFI_MM_COMM_TEE + default 32768 range 4096 2147483647 help This defines the size in bytes of the memory area reserved for keeping @@ -106,7 +107,7 @@ config EFI_VAR_BUF_SIZE match the value of PcdFlashNvStorageVariableSize used to compile the StandAloneMM module.
- Minimum 4096, default 16384. + Minimum 4096, default 32768, or 16384 when using StandAloneMM.
config EFI_GET_TIME bool "GetTime() runtime service"

On 7/8/23 17:21, Alper Nebi Yasak wrote:
Debian's arm64 UEFI Secure Boot shim makes the EFI variable store run out of space while mirroring its MOK database to variables. This can be observed in QEMU like so:
$ tools/buildman/buildman -o build/qemu_arm64 --boards=qemu_arm64 -w $ cd build/qemu_arm64 $ curl -L -o debian.iso \ https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-12.0.0-arm6... $ qemu-system-aarch64 \ -nographic -bios u-boot.bin \ -machine virt -cpu cortex-a53 -m 1G -smp 2 \ -drive if=virtio,file=debian.iso,index=0,format=raw,readonly=on,media=cdrom [...] => # interrupt autoboot => env set -e -bs -nv -rt -guid 605dab50-e046-4300-abb6-3dd810dd8b23 SHIM_VERBOSE 1 => boot [...] mok.c:296:mirror_one_esl() SetVariable("MokListXRT43", ... varsz=0x4C) = Out of Resources mok.c:452:mirror_mok_db() esd:0x7DB92D20 adj:0x30 Failed to set MokListXRT: Out of Resources mok.c:767:mirror_one_mok_variable() mirror_mok_db("MokListXRT", datasz=17328) returned Out of Resources mok.c:812:mirror_one_mok_variable() returning Out of Resources Could not create MokListXRT: Out of Resources [...] Welcome to GRUB!
This would normally be fine as shim would continue to run grubaa64.efi, but shim's error handling code for this case has a bug [1] that causes a synchronous abort on at least chromebook_kevin (but apparently not on QEMU arm64).
Double the default variable store size so the variables fit. There is a note about this value matching PcdFlashNvStorageVariableSize when EFI_MM_COMM_TEE is enabled, so keep the old default in that case.
[1] https://github.com/rhboot/shim/pull/577
Signed-off-by: Alper Nebi Yasak alpernebiyasak@gmail.com
I'm not very familiar with EFI things, apologies if this default should not be changed (consider this a bug report in that case).
lib/efi_loader/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c5835e6ef61a..0660d1174902 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -96,7 +96,8 @@ endif
config EFI_VAR_BUF_SIZE int "Memory size of the UEFI variable store"
- default 16384
- default 16384 if EFI_MM_COMM_TEE
- default 32768
https://learn.microsoft.com/en-us/previous-versions/windows/hardware/cert-pr...
requires 64 KiB.
Best regards
Heinrich
range 4096 2147483647 help This defines the size in bytes of the memory area reserved for keeping @@ -106,7 +107,7 @@ config EFI_VAR_BUF_SIZE match the value of PcdFlashNvStorageVariableSize used to compile the StandAloneMM module.
Minimum 4096, default 16384.
Minimum 4096, default 32768, or 16384 when using StandAloneMM.
config EFI_GET_TIME bool "GetTime() runtime service"

Hi Alper,
On Sat, 8 Jul 2023 at 18:21, Alper Nebi Yasak alpernebiyasak@gmail.com wrote:
Debian's arm64 UEFI Secure Boot shim makes the EFI variable store run out of space while mirroring its MOK database to variables. This can be observed in QEMU like so:
$ tools/buildman/buildman -o build/qemu_arm64 --boards=qemu_arm64 -w $ cd build/qemu_arm64 $ curl -L -o debian.iso \ https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-12.0.0-arm6... $ qemu-system-aarch64 \ -nographic -bios u-boot.bin \ -machine virt -cpu cortex-a53 -m 1G -smp 2 \ -drive if=virtio,file=debian.iso,index=0,format=raw,readonly=on,media=cdrom [...] => # interrupt autoboot => env set -e -bs -nv -rt -guid 605dab50-e046-4300-abb6-3dd810dd8b23 SHIM_VERBOSE 1 => boot [...] mok.c:296:mirror_one_esl() SetVariable("MokListXRT43", ... varsz=0x4C) = Out of Resources mok.c:452:mirror_mok_db() esd:0x7DB92D20 adj:0x30 Failed to set MokListXRT: Out of Resources mok.c:767:mirror_one_mok_variable() mirror_mok_db("MokListXRT", datasz=17328) returned Out of Resources mok.c:812:mirror_one_mok_variable() returning Out of Resources Could not create MokListXRT: Out of Resources [...] Welcome to GRUB!
This would normally be fine as shim would continue to run grubaa64.efi, but shim's error handling code for this case has a bug [1] that causes a synchronous abort on at least chromebook_kevin (but apparently not on QEMU arm64).
Double the default variable store size so the variables fit. There is a note about this value matching PcdFlashNvStorageVariableSize when EFI_MM_COMM_TEE is enabled, so keep the old default in that case.
Thanks for the report. That EFI_MM_COMM_TEE basically means that the variables will be stored in an RPMB partition of an eMMC device. This has a couple of advantages compared to storing it in a file (mostly security related), but I can change that in the future. When you use 32kb how much space do you have left after MoK etc have been written?
Thanks /Ilias
[1] https://github.com/rhboot/shim/pull/577
Signed-off-by: Alper Nebi Yasak alpernebiyasak@gmail.com
I'm not very familiar with EFI things, apologies if this default should not be changed (consider this a bug report in that case).
lib/efi_loader/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c5835e6ef61a..0660d1174902 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -96,7 +96,8 @@ endif
config EFI_VAR_BUF_SIZE int "Memory size of the UEFI variable store"
default 16384
default 16384 if EFI_MM_COMM_TEE
default 32768 range 4096 2147483647 help This defines the size in bytes of the memory area reserved for keeping
@@ -106,7 +107,7 @@ config EFI_VAR_BUF_SIZE match the value of PcdFlashNvStorageVariableSize used to compile the StandAloneMM module.
Minimum 4096, default 16384.
Minimum 4096, default 32768, or 16384 when using StandAloneMM.
config EFI_GET_TIME bool "GetTime() runtime service" -- 2.40.1

Hi Ilias,
On 2023-07-28 14:15 +03:00, Ilias Apalodimas wrote:
On Sat, 8 Jul 2023 at 18:21, Alper Nebi Yasak alpernebiyasak@gmail.com wrote:
Debian's arm64 UEFI Secure Boot shim makes the EFI variable store run out of space while mirroring its MOK database to variables. This can be observed in QEMU like so:
$ tools/buildman/buildman -o build/qemu_arm64 --boards=qemu_arm64 -w $ cd build/qemu_arm64 $ curl -L -o debian.iso \ https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-12.0.0-arm6... $ qemu-system-aarch64 \ -nographic -bios u-boot.bin \ -machine virt -cpu cortex-a53 -m 1G -smp 2 \ -drive if=virtio,file=debian.iso,index=0,format=raw,readonly=on,media=cdrom [...] => # interrupt autoboot => env set -e -bs -nv -rt -guid 605dab50-e046-4300-abb6-3dd810dd8b23 SHIM_VERBOSE 1 => boot [...] mok.c:296:mirror_one_esl() SetVariable("MokListXRT43", ... varsz=0x4C) = Out of Resources mok.c:452:mirror_mok_db() esd:0x7DB92D20 adj:0x30 Failed to set MokListXRT: Out of Resources mok.c:767:mirror_one_mok_variable() mirror_mok_db("MokListXRT", datasz=17328) returned Out of Resources mok.c:812:mirror_one_mok_variable() returning Out of Resources Could not create MokListXRT: Out of Resources [...] Welcome to GRUB!
This would normally be fine as shim would continue to run grubaa64.efi, but shim's error handling code for this case has a bug [1] that causes a synchronous abort on at least chromebook_kevin (but apparently not on QEMU arm64).
Double the default variable store size so the variables fit. There is a note about this value matching PcdFlashNvStorageVariableSize when EFI_MM_COMM_TEE is enabled, so keep the old default in that case.
Thanks for the report. That EFI_MM_COMM_TEE basically means that the variables will be stored in an RPMB partition of an eMMC device. This has a couple of advantages compared to storing it in a file (mostly security related), but I can change that in the future.
I've read your article on it, but haven't really explored this stuff because one-time-programmable things make me a bit afraid.
Mind that this happens even without any persistence at all, i.e. ENV_IS_NOWHERE and EFI_VARIABLE_NO_STORE.
When you use 32kb how much space do you have left after MoK etc have been written?
I can press "c" at the GRUB menu and run "exit" to get back to the U-Boot shell, then I have:
=> efidebug query -bs -rt -nv Max storage size 65512 Remaining storage size 54968 Max variable size 65480
=> env print -e -n SecureBoot: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x1 SetupMode: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x1 AuditMode: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x1 DeployedMode: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x1 VendorKeys: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x1 PlatformLangCodes: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x6 PlatformLang: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) NV|BS|RT, DataSize = 0x6 OsIndicationsSupported: 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) BS|RT|RO, DataSize = 0x8 SbatLevel: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) NV|BS, DataSize = 0x19 MokListRT: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x3ce MokListXRT: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x21d8 SbatLevelRT: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x19 MokListTrustedRT: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x1
It's weird seeing 65512 - 54968 == 10544 < 16K. (Heinrich bumped it to 64K as he applied the patch, based on Windows docs.) But I'm noticing how MokListXRT DataSize 0x21d8 * 2 == 17328 matches the datasz value in the error.
If I retry with 16K, I see 43 extra values each with 0x4c size in addition to the above.
=> efidebug query -bs -rt -nv Max storage size 16360 Remaining storage size 0 Max variable size 16328
=> env print -e -n [...] MokListXRT1: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x4c [..] MokListXRT43: 605dab50-e046-4300-abb6-3dd810dd8b23 (605dab50-e046-4300-abb6-3dd810dd8b23) BS|RT, DataSize = 0x4c
Hope that helps, tell me if there's other commands you want me to run.
participants (3)
-
Alper Nebi Yasak
-
Heinrich Schuchardt
-
Ilias Apalodimas