summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MokVars.txt2
-rw-r--r--include/mok.h2
-rw-r--r--include/pe.h3
-rw-r--r--include/test-data-efivars-1.h1
-rw-r--r--memattrs.c1
-rw-r--r--mok.c5
-rw-r--r--pe-relocate.c37
-rw-r--r--shim.c2
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_ */
diff --git a/memattrs.c b/memattrs.c
index bc571641..ed8a3ae2 100644
--- a/memattrs.c
+++ b/memattrs.c
@@ -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;
diff --git a/mok.c b/mok.c
index cb70e7e2..fb4c1489 100644
--- a/mok.c
+++ b/mok.c
@@ -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
diff --git a/shim.c b/shim.c
index 9efbde11..f85ce00e 100644
--- a/shim.c
+++ b/shim.c
@@ -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);