diff options
| -rw-r--r-- | MokVars.txt | 2 | ||||
| -rw-r--r-- | include/mok.h | 2 | ||||
| -rw-r--r-- | include/pe.h | 3 | ||||
| -rw-r--r-- | include/test-data-efivars-1.h | 1 | ||||
| -rw-r--r-- | memattrs.c | 1 | ||||
| -rw-r--r-- | mok.c | 5 | ||||
| -rw-r--r-- | pe-relocate.c | 37 | ||||
| -rw-r--r-- | shim.c | 2 |
8 files changed, 48 insertions, 5 deletions
diff --git a/MokVars.txt b/MokVars.txt index 0ab81ff6..6ad8ce70 100644 --- a/MokVars.txt +++ b/MokVars.txt @@ -109,3 +109,5 @@ HSIStatus: Status of various security features: 1: platform's DST does populate GetMemorySpaceDescriptor has-set-memory-space-descriptor: 0: platform's DST does not populate SetMemorySpaceDescriptor 1: platform's DST does populate SetMemorySpaceDescriptor + shim-has-nx-compat-set: 0: the running shim binary does not have NX_COMPAT bit set + 1: the running shim binary does have the NX_COMPAT bit set diff --git a/include/mok.h b/include/mok.h index cea4c997..89edf9de 100644 --- a/include/mok.h +++ b/include/mok.h @@ -147,6 +147,8 @@ extern UINTN hsi_status; #define SHIM_HSI_STATUS_HASDSTGMSD 0x00000020ULL /* platform has DST->SetMemorySpaceAttributes */ #define SHIM_HSI_STATUS_HASDSTSMSA 0x00000040ULL +/* This shim has the NX_COMPAT bit set */ +#define SHIM_HSI_STATUS_NX 0x00000100ULL #endif /* !SHIM_MOK_H_ */ // vim:fenc=utf-8:tw=75:noet diff --git a/include/pe.h b/include/pe.h index a1eb8853..ea40184b 100644 --- a/include/pe.h +++ b/include/pe.h @@ -53,5 +53,8 @@ relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context, EFI_IMAGE_SECTION_HEADER *Section, void *orig, void *data); +void +get_shim_nx_capability(EFI_HANDLE image_handle); + #endif /* !PE_H_ */ // vim:fenc=utf-8:tw=75:noet diff --git a/include/test-data-efivars-1.h b/include/test-data-efivars-1.h index 7a34ea70..259558e0 100644 --- a/include/test-data-efivars-1.h +++ b/include/test-data-efivars-1.h @@ -114,6 +114,7 @@ static const unsigned char test_data_efivars_1_HSIStatus[] = "has-dxe-services-table: 0\n" "has-get-memory-space-descriptor: 0\n" "has-set-memory-space-attributes: 0\n" + "shim-has-nx-compat-set: 0\n" ; #endif /* !TEST_DATA_EFIVARS_1_H_ */ @@ -414,6 +414,7 @@ decode_hsi_bits(UINTN hsi) {.bit = SHIM_HSI_STATUS_HASDST, .name = "HASDST"}, {.bit = SHIM_HSI_STATUS_HASDSTGMSD, .name = "HASDSTGMSD"}, {.bit = SHIM_HSI_STATUS_HASDSTSMSA, .name = "HASDSTSMSA"}, + {.bit = SHIM_HSI_STATUS_NX, .name = "NX"}, {.bit = 0, .name = ""}, }; static int x = 0; @@ -45,6 +45,7 @@ format_hsi_status(UINT8 *buf, size_t sz, 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; @@ -55,7 +56,7 @@ format_hsi_status(UINT8 *buf, size_t sz, UINTN ret = sizeof(heapx) + sizeof(stackx) + sizeof(row) + sizeof(hasmap) + sizeof(hasdxeservices) + sizeof(hasdsgmsd) + - sizeof(hasdssmsa) + + sizeof(hasdssmsa) + sizeof(shimhasnx) + sizeof(finale); if (buf == 0 || sz < ret) { @@ -78,6 +79,8 @@ format_hsi_status(UINT8 *buf, size_t sz, 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; diff --git a/pe-relocate.c b/pe-relocate.c index b436d3ec..4991dbe1 100644 --- a/pe-relocate.c +++ b/pe-relocate.c @@ -375,7 +375,6 @@ read_header(void *data, unsigned int datasize, EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data; unsigned long HeaderWithoutDataDir, SectionHeaderOffset, OptHeaderSize; unsigned long FileAlignment = 0; - UINT16 DllFlags; size_t dos_sz = 0; size_t tmpsz0, tmpsz1; @@ -504,17 +503,17 @@ read_header(void *data, unsigned int datasize, context->EntryPoint = PEHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint; context->RelocDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; context->SecDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]; - DllFlags = PEHdr->Pe32Plus.OptionalHeader.DllCharacteristics; + context->DllCharacteristics = PEHdr->Pe32Plus.OptionalHeader.DllCharacteristics; } else { context->ImageAddress = PEHdr->Pe32.OptionalHeader.ImageBase; context->EntryPoint = PEHdr->Pe32.OptionalHeader.AddressOfEntryPoint; context->RelocDir = &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; context->SecDir = &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]; - DllFlags = PEHdr->Pe32.OptionalHeader.DllCharacteristics; + context->DllCharacteristics = PEHdr->Pe32.OptionalHeader.DllCharacteristics; } if ((mok_policy & MOK_POLICY_REQUIRE_NX) && - !(DllFlags & EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT)) { + !(context->DllCharacteristics & EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT)) { perror(L"Policy requires NX, but image does not support NX\n"); return EFI_UNSUPPORTED; } @@ -555,4 +554,34 @@ read_header(void *data, unsigned int datasize, return EFI_SUCCESS; } +void +get_shim_nx_capability(EFI_HANDLE image_handle) +{ + EFI_LOADED_IMAGE_PROTOCOL*li = NULL; + EFI_STATUS efi_status; + PE_COFF_LOADER_IMAGE_CONTEXT context; + + efi_status = BS->HandleProtocol(image_handle, &gEfiLoadedImageProtocolGuid, (void **)&li); + if (EFI_ERROR(efi_status) || !li) { + dprint(L"Could not get loaded image protocol: %r\n", efi_status); + return; + } + + ZeroMem(&context, sizeof(context)); + efi_status = read_header(li->ImageBase, li->ImageSize, &context, false); + if (EFI_ERROR(efi_status)) { + dprint(L"Couldn't parse image header: %r\n", efi_status); + return; + } + + dprint(L"DllCharacteristics:0x%lx\n", context.DllCharacteristics); + if (context.DllCharacteristics & EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT) { + dprint(L"Setting HSI from %a to %a\n", + decode_hsi_bits(hsi_status), + decode_hsi_bits(hsi_status | SHIM_HSI_STATUS_NX)); + hsi_status |= SHIM_HSI_STATUS_NX; + } +} + + // vim:fenc=utf-8:tw=75:noet @@ -1993,6 +1993,8 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab) */ debug_hook(); + get_shim_nx_capability(image_handle); + efi_status = set_sbat_uefi_variable_internal(); if (EFI_ERROR(efi_status) && secure_mode()) { perror(L"%s variable initialization failed\n", SBAT_VAR_NAME); |
