diff options
| author | Christian Breunig <christian@breunig.cc> | 2025-07-06 21:59:18 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2025-07-06 21:59:18 +0200 |
| commit | 02acad285c74015e8120ade2b41d51b39ae66b63 (patch) | |
| tree | 980533ac963ac23bc9e090e3e4212bdb9e225a05 /mok.c | |
| parent | 1c1d50da810e6c49e804a74719c2675b88b033a6 (diff) | |
| parent | 18d98bfb34be583a5fe2987542e4b15e0db9cb61 (diff) | |
| download | efi-boot-shim-02acad285c74015e8120ade2b41d51b39ae66b63.tar.gz efi-boot-shim-02acad285c74015e8120ade2b41d51b39ae66b63.zip | |
Merge tag '16.0' into vyos/current
shim-16.0
What's Changed
* Validate that a supplied vendor cert is not in PEM format by @steve-mcintyre in https://github.com/rhboot/shim/pull/646
* sbat: Add grub.peimage,2 to latest (CVE-2024-2312) by @julian-klode in https://github.com/rhboot/shim/pull/651
* sbat: Also bump latest for grub,4 (and to todays date) by @julian-klode in https://github.com/rhboot/shim/pull/653
* undo change that limits certificate files to a single file by @jsetje in https://github.com/rhboot/shim/pull/659
* shim: don't set second_stage to the empty string by @jjd27 in https://github.com/rhboot/shim/pull/640
* Fix SBAT.md for today's consensus about numbers by @aronowski in https://github.com/rhboot/shim/pull/672
* Update Code of Conduct contact address by @aronowski in https://github.com/rhboot/shim/pull/683
* make-certs: Handle missing OpenSSL installation by @aronowski in https://github.com/rhboot/shim/pull/595
* Update MokVars.txt by @mikebeaton in https://github.com/rhboot/shim/pull/598
* export DEFINES for sub makefile by @bryteise in https://github.com/rhboot/shim/pull/600
* Drop unused EFI_IMAGE_SECURITY_DATABASE_GUID definition by @vittyvk in https://github.com/rhboot/shim/pull/609
* Null-terminate 'arguments' in fallback by @vittyvk in https://github.com/rhboot/shim/pull/611
* Fix "Verifiying" typo in error message by @chrisbainbridge in https://github.com/rhboot/shim/pull/706
* Update Fedora CI targets by @vathpela in https://github.com/rhboot/shim/pull/708
* Force gcc to produce DWARF4 so that gdb can use it by @mikebeaton in https://github.com/rhboot/shim/pull/607
* Minor housekeeping 2024121700 by @vathpela in https://github.com/rhboot/shim/pull/709
* Discard load-options that start with WINDOWS by @Metabolix in https://github.com/rhboot/shim/pull/621
* Fix the issue that the gBS->LoadImage pointer was empty. by @15058718379 in https://github.com/rhboot/shim/pull/703
* shim: Allow data after the end of device path node in load options by @dbnicholson in https://github.com/rhboot/shim/pull/694
* Handle network file not found like disks by @dbnicholson in https://github.com/rhboot/shim/pull/695
* Update gnu-efi submodule for EFI_HTTP_ERROR by @vathpela in https://github.com/rhboot/shim/pull/674
* Increase EFI file alignment by @lumag in https://github.com/rhboot/shim/pull/673
* avoid EFIv2 runtime services on Apple x86 machines by @eduardacatrinei in https://github.com/rhboot/shim/pull/690
* Improve shortcut performance when comparing two boolean expressions by @dennis-tseng99 in https://github.com/rhboot/shim/pull/667
* Provide better error message when MokManager is not found by @rmetrich in https://github.com/rhboot/shim/pull/663
* tpm: Boot with a warning if the event log is full by @kukrimate in https://github.com/rhboot/shim/pull/657
* MokManager: remove redundant logical constraints by @xypron in https://github.com/rhboot/shim/pull/409
* Test import_mok_state() when MokListRT would be bigger than available size by @vathpela in https://github.com/rhboot/shim/pull/417
* test-mok-mirror: minor bug fix by @vathpela in https://github.com/rhboot/shim/pull/715
* Fix file system browser hang when enrolling MOK from disk by @miczyg1 in https://github.com/rhboot/shim/pull/622
* Ignore a minor clang-tidy nit by @vathpela in https://github.com/rhboot/shim/pull/716
* Allow fallback to default loader when encountering errors on network boot by @nathan-omeara in https://github.com/rhboot/shim/pull/666
* test.mk: don't use a temporary random.bin by @vathpela in https://github.com/rhboot/shim/pull/718
* pe: Enhance debug report for update_mem_attrs by @jongwu in https://github.com/rhboot/shim/pull/594
* Multiple certificate handling improvements by @rosslagerwall in https://github.com/rhboot/shim/pull/644
* Generate SbatLevel Metadata from SbatLevel_Variable.txt by @jsetje in https://github.com/rhboot/shim/pull/711
* Apply EKU check with compile option by @dennis-tseng99 in https://github.com/rhboot/shim/pull/664
* Add configuration option to boot an alternative 2nd stage by @esnowberg in https://github.com/rhboot/shim/pull/608
* Loader protocol (with Device Path resolution support) by @kukrimate in https://github.com/rhboot/shim/pull/656
* netboot cleanup for additional files by @jsetje in https://github.com/rhboot/shim/pull/686
* Document how revocations can be delivered by @jsetje in https://github.com/rhboot/shim/pull/722
* post-process-pe: add tests to validate NX compliance by @vathpela in https://github.com/rhboot/shim/pull/705
* regression: CopyMem() in ad8692e copies out of bounds by @jsetje in https://github.com/rhboot/shim/pull/725
* Save the debug and error logs in mok-variables by @vathpela in https://github.com/rhboot/shim/pull/726
* Add features for the Host Security ID program by @vathpela in https://github.com/rhboot/shim/pull/660
* Mirror some more efi variables to mok-variables by @vathpela in https://github.com/rhboot/shim/pull/723
* This adds DXE Services measurements to HSI and uses them for NX by @vathpela in https://github.com/rhboot/shim/pull/724
* Add shim's current NX_COMPAT status to HSIStatus by @vathpela in https://github.com/rhboot/shim/pull/727
* README.tpm: reflect that vendor_db is in fact logged as "vendor_db" by @jsetje in https://github.com/rhboot/shim/pull/728
* Reject HTTP message with duplicate Content-Length header fields by @dennis-tseng99 in https://github.com/rhboot/shim/pull/637
* Disable log saving by @vathpela in https://github.com/rhboot/shim/pull/729
* fallback: don't add new boot order entries backwards by @vathpela in https://github.com/rhboot/shim/pull/730
* Misc fixes... by @vathpela in https://github.com/rhboot/shim/pull/735
* README.tpm: Update MokList entry to MokListRT by @trungams in https://github.com/rhboot/shim/pull/732
* SBAT Level update for February 2025 GRUB CVEs by @jsetje in https://github.com/rhboot/shim/pull/736
New Contributors
* @jjd27 made their first contribution in https://github.com/rhboot/shim/pull/640
* @mikebeaton made their first contribution in https://github.com/rhboot/shim/pull/598
* @bryteise made their first contribution in https://github.com/rhboot/shim/pull/600
* @vittyvk made their first contribution in https://github.com/rhboot/shim/pull/609
* @chrisbainbridge made their first contribution in https://github.com/rhboot/shim/pull/706
* @Metabolix made their first contribution in https://github.com/rhboot/shim/pull/621
* @15058718379 made their first contribution in https://github.com/rhboot/shim/pull/703
* @dbnicholson made their first contribution in https://github.com/rhboot/shim/pull/694
* @lumag made their first contribution in https://github.com/rhboot/shim/pull/673
* @eduardacatrinei made their first contribution in https://github.com/rhboot/shim/pull/690
* @kukrimate made their first contribution in https://github.com/rhboot/shim/pull/657
* @miczyg1 made their first contribution in https://github.com/rhboot/shim/pull/622
* @nathan-omeara made their first contribution in https://github.com/rhboot/shim/pull/666
* @jongwu made their first contribution in https://github.com/rhboot/shim/pull/594
* @rosslagerwall made their first contribution in https://github.com/rhboot/shim/pull/644
* @trungams made their first contribution in https://github.com/rhboot/shim/pull/732
**Full Changelog**: https://github.com/rhboot/shim/compare/15.8...16.0
* tag '16.0': (451 commits)
Update version to 16.0
SBAT Level update for February 2025 GRUB CVEs
README.tpm: Update MokList entry to MokListRT
Make 'make fanalyzer' work again.
simple_dir_filter(): test our 'next' pointer
shim_load_image(): initialize the buffer fully
mirror_mok_db(): Free our mok variable name correctly
mirror_one_mok_variable(): fix a memory leak on TPM log error.
mirror_mok_db(): get rid of an unused variable+allocation
generate_sbat_var_defs: Ensure revlistentry->revocations is initialized.
generate_sbat_var_defs: Fix memory leak on realloc failure and fd leak.
generate_sbat_var_defs: run clang-format on readfile()
SetSecureVariable(): free Cert on failure
Update version to 16.0~rc1
make-archive: some minor housekeeping
makefiles: Make GITTAG swizzle tildes to dashes
fallback: don't add new boot order entries backwards
Disable log saving for now.
Some save_logs() improvements.
reject message with different values in multiple Content-Length header field
...
Diffstat (limited to 'mok.c')
| -rw-r--r-- | mok.c | 363 |
1 files changed, 331 insertions, 32 deletions
@@ -34,6 +34,58 @@ static BOOLEAN check_var(CHAR16 *varname) efi_status_; \ }) +static UINTN +format_hsi_status(UINT8 *buf, size_t sz, + struct mok_state_variable *msv UNUSED) +{ + const char heapx[] = "heap-is-executable: "; + const char stackx[] = "\nstack-is-executable: "; + const char row[] = "\nro-sections-are-writable: "; + const char hasmap[] = "\nhas-memory-attribute-protocol: "; + const char hasdxeservices[] = "\nhas-dxe-services-table: "; + const char hasdsgmsd[] = "\nhas-get-memory-space-descriptor: "; + const char hasdssmsa[] = "\nhas-set-memory-space-attributes: "; + const char shimhasnx[] = "\nshim-has-nx-compat-set: "; + const char finale[] = "\n"; + char *pos; + + /* + * sizeof includes the trailing NUL which is where our 0 or 1 value + * fits + */ + UINTN ret = sizeof(heapx) + sizeof(stackx) + + sizeof(row) + sizeof(hasmap) + + sizeof(hasdxeservices) + sizeof(hasdsgmsd) + + sizeof(hasdssmsa) + sizeof(shimhasnx) + + sizeof(finale); + + if (buf == 0 || sz < ret) { + return ret; + } + + buf[0] = 0; + pos = (char *)buf; + pos = stpcpy(pos, heapx); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_HEAPX) ? "1" : "0"); + pos = stpcpy(pos, stackx); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_STACKX) ? "1" : "0"); + pos = stpcpy(pos, row); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_ROW) ? "1" : "0"); + pos = stpcpy(pos, hasmap); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_HASMAP) ? "1" : "0"); + pos = stpcpy(pos, hasdxeservices); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_HASDST) ? "1" : "0"); + pos = stpcpy(pos, hasdsgmsd); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_HASDSTGMSD) ? "1" : "0"); + pos = stpcpy(pos, hasdssmsa); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_HASDSTSMSA) ? "1" : "0"); + pos = stpcpy(pos, shimhasnx); + pos = stpcpy(pos, (hsi_status & SHIM_HSI_STATUS_NX) ? "1" : "0"); + stpcpy(pos, finale); + + return ret; +} + /* * If the OS has set any of these variables we need to drop into MOK and * handle them appropriately @@ -50,6 +102,32 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) efi_status = start_image(image_handle, MOK_MANAGER); if (EFI_ERROR(efi_status)) { + /* + * We don't do this in the unit tests because we + * don't have simulation for console_countdown() + * and similar. + */ +#ifndef SHIM_UNIT_TEST + EFI_STATUS efi_status_2; + EFI_LOADED_IMAGE *li; + efi_status_2 = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID, + (void **)&li); + if (EFI_ERROR(efi_status_2)) + perror (L"Failed to get image: %r\n", efi_status_2); + else if (is_removable_media_path(li) && + efi_status == EFI_NOT_FOUND) { + CHAR16 *title = L"Could not find MokManager"; + CHAR16 *message = L"MokManager is missing on removable media."; + /* + * This occurs when system is booting on + * hard disk's EFI/BOOT/BOOTxxx.EFI entry + * while it should have booted on + * EFI/<os>/shimxxx.efi entry + */ + console_countdown(title, message, 10); + RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); + } +#endif perror(L"Failed to start MokManager: %r\n", efi_status); return efi_status; } @@ -80,12 +158,6 @@ categorize_deauthorized(struct mok_state_variable *v) return VENDOR_ADDEND_DB; } -#define MOK_MIRROR_KEYDB 0x01 -#define MOK_MIRROR_DELETE_FIRST 0x02 -#define MOK_VARIABLE_MEASURE 0x04 -#define MOK_VARIABLE_LOG 0x08 -#define MOK_VARIABLE_INVERSE 0x10 - struct mok_state_variable mok_state_variable_data[] = { {.name = L"MokList", .name8 = "MokList", @@ -196,6 +268,161 @@ struct mok_state_variable mok_state_variable_data[] = { .pcr = 14, .state = &mok_policy, }, + {.name = L"HSIStatus", + .name8 = "HSIStatus", + .rtname = L"HSIStatus", + .rtname8 = "HSIStatus", + .guid = &SHIM_LOCK_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + .format = format_hsi_status, + }, + {.name = L"AuditMode", + .name8 = "AuditMode", + .rtname = L"AuditMode", + .rtname8 = "AuditMode", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"BootOrder", + .name8 = "BootOrder", + .rtname = L"BootOrder", + .rtname8 = "BootOrder", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"BootCurrent", + .name8 = "BootCurrent", + .rtname = L"BootCurrent", + .rtname8 = "BootCurrent", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"BootNext", + .name8 = "BootNext", + .rtname = L"BootNext", + .rtname8 = "BootNext", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0000", + .name8 = "Boot0000", + .rtname = L"Boot0000", + .rtname8 = "Boot0000", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0001", + .name8 = "Boot0001", + .rtname = L"Boot0001", + .rtname8 = "Boot0001", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0002", + .name8 = "Boot0002", + .rtname = L"Boot0002", + .rtname8 = "Boot0002", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0003", + .name8 = "Boot0003", + .rtname = L"Boot0003", + .rtname8 = "Boot0003", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0004", + .name8 = "Boot0004", + .rtname = L"Boot0004", + .rtname8 = "Boot0004", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0005", + .name8 = "Boot0005", + .rtname = L"Boot0005", + .rtname8 = "Boot0005", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Boot0006", + .name8 = "Boot0006", + .rtname = L"Boot0006", + .rtname8 = "Boot0006", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"DeployedMode", + .name8 = "DeployedMode", + .rtname = L"DeployedMode", + .rtname8 = "DeployedMode", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"SecureBoot", + .name8 = "SecureBoot", + .rtname = L"SecureBoot", + .rtname8 = "SecureBoot", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"SetupMode", + .name8 = "SetupMode", + .rtname = L"SetupMode", + .rtname8 = "SetupMode", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"SignatureSupport", + .name8 = "SignatureSupport", + .rtname = L"SignatureSupport", + .rtname8 = "SignatureSupport", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Timeout", + .name8 = "Timeout", + .rtname = L"Timeout", + .rtname8 = "Timeout", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"PK", + .name8 = "PK", + .rtname = L"PK", + .rtname8 = "PK", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"KEK", + .name8 = "KEK", + .rtname = L"KEK", + .rtname8 = "KEK", + .guid = &GV_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"db", + .name8 = "db", + .rtname = L"db", + .rtname8 = "db", + .guid = &SIG_DB, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"dbx", + .name8 = "dbx", + .rtname = L"dbx", + .rtname8 = "dbx", + .guid = &SIG_DB, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, + {.name = L"Kernel_SkuSiStatus", + .name8 = "Kernel_SkuSiStatus", + .rtname = L"Kernel_SkuSiStatus", + .rtname8 = "Kernel_SkuSiStatus", + .guid = &SECUREBOOT_EFI_NAMESPACE_GUID, + .flags = MOK_VARIABLE_CONFIG_ONLY, + }, { NULL, } }; size_t n_mok_state_variables = sizeof(mok_state_variable_data) / sizeof(mok_state_variable_data[0]); @@ -217,6 +444,47 @@ typedef UINTN SIZE_T; #define EFI_MAJOR_VERSION(tablep) ((UINT16)((((tablep)->Hdr.Revision) >> 16) & 0xfffful)) #define EFI_MINOR_VERSION(tablep) ((UINT16)(((tablep)->Hdr.Revision) & 0xfffful)) +static BOOLEAN is_apple_firmware_vendor(void) +{ + CHAR16 vendorbuf[6] = L""; + CHAR16 *vendor = ST->FirmwareVendor; + if (!vendor) + return FALSE; + + ZeroMem(vendorbuf, sizeof(vendorbuf)); + + /* + * We've had a problem where ST->FirmwareVendor is only as big as + * it needs to be (or at least less than the 200 bytes we formerly + * defined vendorbuf as) and it's up against a page that's not + * mapped readable, so we take a fault and reset when copying from + * it. + * + * We modeled this after kernel, which has the 200 byte CHAR16 + * array and copies 198 bytes into it, so that there's a NUL + * terminator. They solve this issue by mapping the whole 200 + * bytes unconditionally and then unmapping it after the copy, but + * we can't take that approach because we don't necessarily have + * page permission primitives at all. + * + * The 200 bytes (CHAR16 [100]) is an arbitrary number anyway, but + * it's likely larger than any sane vendor name, and we still want + * to do the copy into an array larger than our copied data because + * that's how we guard against failure to terminate with a NUL. + * + * So right now we're only copying ten bytes, because Apple is the + * only vendor we're testing against. + */ + CopyMem(vendorbuf, vendor, 10); + + dprint(L"FirmwareVendor: \"%s\"\n", vendor); + + if (StrnCmp(vendor, L"Apple", 5) == 0) + return TRUE; + + return FALSE; +} + static EFI_STATUS get_max_var_sz(UINT32 attrs, SIZE_T *max_var_szp) { @@ -226,7 +494,7 @@ get_max_var_sz(UINT32 attrs, SIZE_T *max_var_szp) uint64_t max_var_sz = 0; *max_var_szp = 0; - if (EFI_MAJOR_VERSION(RT) < 2) { + if (EFI_MAJOR_VERSION(RT) < 2 || is_apple_firmware_vendor()) { dprint(L"EFI %d.%d; no RT->QueryVariableInfo(). Using 1024!\n", EFI_MAJOR_VERSION(RT), EFI_MINOR_VERSION(RT)); max_var_sz = remaining_sz = max_storage_sz = 1024; @@ -310,7 +578,7 @@ mirror_one_esl(CHAR16 *name, EFI_GUID *guid, UINT32 attrs, } static EFI_STATUS -mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, +mirror_mok_db(CHAR16 *name, EFI_GUID *guid, UINT32 attrs, UINT8 *FullData, SIZE_T FullDataSize, BOOLEAN only_first) { EFI_STATUS efi_status = EFI_SUCCESS; @@ -336,15 +604,13 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, return efi_status; } - CHAR16 *namen; - CHAR8 *namen8; + CHAR16 *namen = NULL; UINTN namelen, namesz; namelen = StrLen(name); namesz = namelen * 2; if (only_first) { namen = name; - namen8 = name8; } else { namelen += 18; namesz += 34; @@ -353,12 +619,6 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, LogError(L"Could not allocate %lu bytes", namesz); return EFI_OUT_OF_RESOURCES; } - namen8 = AllocateZeroPool(namelen); - if (!namen8) { - FreePool(namen); - LogError(L"Could not allocate %lu bytes", namelen); - return EFI_OUT_OF_RESOURCES; - } } UINTN pos, i; @@ -400,11 +660,6 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, if (!only_first) { SPrint(namen, namelen, L"%s%lu", name, i); namen[namelen-1] = 0; - /* uggggh */ - UINTN j; - for (j = 0; j < namelen; j++) - namen8[j] = (CHAR8)(namen[j] & 0xff); - namen8[namelen - 1] = 0; } /* @@ -417,7 +672,6 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, efi_status); if (!only_first) { FreePool(namen); - FreePool(namen8); } return efi_status; } @@ -472,6 +726,9 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, break; i++; } + if (namen && namen != name) { + FreePool(namen); + } if (EFI_ERROR(efi_status)) { perror(L"Failed to set %s: %r\n", name, efi_status); @@ -515,6 +772,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS efi_status = EFI_SUCCESS; uint8_t *FullData = NULL; size_t FullDataSize = 0; + bool allocated_full_data = false; vendor_addend_category_t addend_category = VENDOR_ADDEND_NONE; uint8_t *p = NULL; uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | @@ -579,6 +837,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, if (efi_status != EFI_BUFFER_TOO_SMALL) { perror(L"Could not add built-in cert to %s: %r\n", v->name, efi_status); + goto err; return efi_status; } FullDataSize += addend_esl_sz; @@ -663,6 +922,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, FullDataSize, v->name); return EFI_OUT_OF_RESOURCES; } + allocated_full_data = true; p = FullData; } } @@ -692,7 +952,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, if (EFI_ERROR(efi_status)) { perror(L"Could not add built-in cert to %s: %r\n", v->name, efi_status); - return efi_status; + goto err; } p += addend_esl_sz; dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n", @@ -719,7 +979,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, if (EFI_ERROR(efi_status)) { perror(L"Could not add built-in cert to %s: %r\n", v->name, efi_status); - return efi_status; + goto err; } p += build_cert_esl_sz; dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n", @@ -758,7 +1018,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, if (EFI_ERROR(efi_status)) { perror(L"Failed to allocate %lu bytes for %s\n", FullDataSize, v->name); - return efi_status; + goto err; } p = FullData + FullDataSize; dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n", @@ -767,15 +1027,17 @@ mirror_one_mok_variable(struct mok_state_variable *v, dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n", FullDataSize, FullData, p, p-(uintptr_t)FullData); - if (FullDataSize && v->flags & MOK_MIRROR_KEYDB) { + if (FullDataSize && v->flags & MOK_MIRROR_KEYDB && + !(v->flags & MOK_VARIABLE_CONFIG_ONLY)) { dprint(L"calling mirror_mok_db(\"%s\", datasz=%lu)\n", v->rtname, FullDataSize); - efi_status = mirror_mok_db(v->rtname, (CHAR8 *)v->rtname8, v->guid, + efi_status = mirror_mok_db(v->rtname, v->guid, attrs, FullData, FullDataSize, only_first); dprint(L"mirror_mok_db(\"%s\", datasz=%lu) returned %r\n", v->rtname, FullDataSize, efi_status); - } else if (FullDataSize && only_first) { + } else if (FullDataSize && only_first && + !(v->flags & MOK_VARIABLE_CONFIG_ONLY)) { efi_status = SetVariable(v->rtname, v->guid, attrs, FullDataSize, FullData); } @@ -789,7 +1051,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, if (EFI_ERROR(efi_status)) { dprint(L"tpm_measure_variable(\"%s\",%lu,0x%llx)->%r\n", v->name, FullDataSize, FullData, efi_status); - return efi_status; + goto err; } } @@ -806,7 +1068,7 @@ mirror_one_mok_variable(struct mok_state_variable *v, dprint(L"tpm_log_event(0x%llx, %lu, %lu, \"%s\")->%r\n", FullData, FullDataSize, v->pcr, v->name, efi_status); - return efi_status; + goto err; } } @@ -820,6 +1082,10 @@ mirror_one_mok_variable(struct mok_state_variable *v, v->data_size = FullDataSize; dprint(L"returning %r\n", efi_status); return efi_status; +err: + if (FullData && allocated_full_data) + FreePool(FullData); + return efi_status; } /* @@ -871,7 +1137,8 @@ EFI_STATUS import_one_mok_state(struct mok_state_variable *v, dprint(L"importing mok state for \"%s\"\n", v->name); - if (!v->data && !v->data_size) { + if (!v->data && !v->data_size && + !(v->flags & MOK_VARIABLE_CONFIG_ONLY)) { efi_status = get_variable_attr(v->name, &v->data, &v->data_size, *v->guid, &attrs); @@ -913,6 +1180,36 @@ EFI_STATUS import_one_mok_state(struct mok_state_variable *v, } } } + + if (v->format) { + v->data_size = v->format(NULL, 0, v); + if (v->data_size > 0) { + v->data = AllocatePool(v->data_size); + if (!v->data) { + perror(L"Could not allocate %lu bytes for %s\n", + v->data_size, v->name); + return EFI_OUT_OF_RESOURCES; + } + } + v->format(v->data, v->data_size, v); + } + + if (!v->data && !v->data_size && + (v->flags & MOK_VARIABLE_CONFIG_ONLY) && + !v->format) { + efi_status = get_variable_attr(v->name, + &v->data, &v->data_size, + *v->guid, &attrs); + if (EFI_ERROR(efi_status)) { + dprint(L"Couldn't get variable \"%s\" for mirroring: %r\n", + v->name, efi_status); + if (efi_status != EFI_NOT_FOUND) + return efi_status; + v->data = NULL; + v->data_size = 0; + } + } + if (delete == TRUE) { perror(L"Deleting bad variable %s\n", v->name); efi_status = LibDeleteVariable(v->name, v->guid); @@ -1004,6 +1301,8 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle) config_table = NULL; } else { ZeroMem(config_table, npages << EFI_PAGE_SHIFT); + mok_config_table = (EFI_PHYSICAL_ADDRESS)(uintptr_t)config_table; + mok_config_table_pages = npages; } } |
