summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--include/memattrs.h15
-rw-r--r--memattrs.c167
-rw-r--r--pe.c152
-rw-r--r--shim.h1
5 files changed, 185 insertions, 154 deletions
diff --git a/Makefile b/Makefile
index bf339fab..fe42db40 100644
--- a/Makefile
+++ b/Makefile
@@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT
else
TARGETS += $(MMNAME) $(FBNAME)
endif
-OBJS = shim.o globals.o mok.o netboot.o cert.o dp.o loader-proto.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o
+OBJS = shim.o globals.o memattrs.o mok.o netboot.o cert.o dp.o loader-proto.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
-ORIG_SOURCES = shim.c globals.c mok.c netboot.c dp.c loader-proto.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
+ORIG_SOURCES = shim.c globals.c memattrs.c mok.c netboot.c dp.c loader-proto.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o dp.o
ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o utils.o
diff --git a/include/memattrs.h b/include/memattrs.h
new file mode 100644
index 00000000..8fefef22
--- /dev/null
+++ b/include/memattrs.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * memattrs.h - EFI and DXE memory attribute helpers
+ * Copyright Peter Jones <pjones@redhat.com>
+ */
+
+#ifndef SHIM_MEMATTRS_H_
+#define SHIM_MEMATTRS_H_
+
+extern EFI_STATUS get_mem_attrs (uintptr_t addr, size_t size, uint64_t *attrs);
+extern EFI_STATUS update_mem_attrs(uintptr_t addr, uint64_t size,
+ uint64_t set_attrs, uint64_t clear_attrs);
+
+#endif /* !SHIM_MEMATTRS_H_ */
+// vim:fenc=utf-8:tw=75:noet
diff --git a/memattrs.c b/memattrs.c
new file mode 100644
index 00000000..99268cd1
--- /dev/null
+++ b/memattrs.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * memattrs.c - EFI and DXE memory attribute helpers
+ * Copyright Peter Jones <pjones@redhat.com>
+ */
+
+#include "shim.h"
+
+static inline uint64_t
+shim_mem_attrs_to_uefi_mem_attrs (uint64_t attrs)
+{
+ uint64_t ret = EFI_MEMORY_RP |
+ EFI_MEMORY_RO |
+ EFI_MEMORY_XP;
+
+ if (attrs & MEM_ATTR_R)
+ ret &= ~EFI_MEMORY_RP;
+
+ if (attrs & MEM_ATTR_W)
+ ret &= ~EFI_MEMORY_RO;
+
+ if (attrs & MEM_ATTR_X)
+ ret &= ~EFI_MEMORY_XP;
+
+ return ret;
+}
+
+static inline uint64_t
+uefi_mem_attrs_to_shim_mem_attrs (uint64_t attrs)
+{
+ uint64_t ret = MEM_ATTR_R |
+ MEM_ATTR_W |
+ MEM_ATTR_X;
+
+ if (attrs & EFI_MEMORY_RP)
+ ret &= ~MEM_ATTR_R;
+
+ if (attrs & EFI_MEMORY_RO)
+ ret &= ~MEM_ATTR_W;
+
+ if (attrs & EFI_MEMORY_XP)
+ ret &= ~MEM_ATTR_X;
+
+ return ret;
+}
+
+EFI_STATUS
+get_mem_attrs (uintptr_t addr, size_t size, uint64_t *attrs)
+{
+ EFI_MEMORY_ATTRIBUTE_PROTOCOL *proto = NULL;
+ EFI_PHYSICAL_ADDRESS physaddr = addr;
+ EFI_STATUS efi_status;
+
+ efi_status = LibLocateProtocol(&EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID,
+ (VOID **)&proto);
+ if (EFI_ERROR(efi_status) || !proto) {
+ dprint(L"No memory attribute protocol found: %r\n", efi_status);
+ if (!EFI_ERROR(efi_status))
+ efi_status = EFI_UNSUPPORTED;
+ return efi_status;
+ }
+
+ if (!IS_PAGE_ALIGNED(physaddr) || !IS_PAGE_ALIGNED(size) || size == 0 || attrs == NULL) {
+ dprint(L"%a called on 0x%llx-0x%llx and attrs 0x%llx\n",
+ __func__, (unsigned long long)physaddr,
+ (unsigned long long)(physaddr+size-1),
+ attrs);
+ return EFI_SUCCESS;
+ }
+
+ efi_status = proto->GetMemoryAttributes(proto, physaddr, size, attrs);
+ if (EFI_ERROR(efi_status)) {
+ dprint(L"GetMemoryAttributes(..., 0x%llx, 0x%x, 0x%x): %r\n",
+ physaddr, size, attrs, efi_status);
+ } else {
+ *attrs = uefi_mem_attrs_to_shim_mem_attrs (*attrs);
+ }
+
+ return efi_status;
+}
+
+EFI_STATUS
+update_mem_attrs(uintptr_t addr, uint64_t size,
+ uint64_t set_attrs, uint64_t clear_attrs)
+{
+ EFI_MEMORY_ATTRIBUTE_PROTOCOL *proto = NULL;
+ EFI_PHYSICAL_ADDRESS physaddr = addr;
+ EFI_STATUS efi_status, ret;
+ uint64_t before = 0, after = 0, uefi_set_attrs, uefi_clear_attrs;
+
+ efi_status = LibLocateProtocol(&EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID,
+ (VOID **)&proto);
+ if (EFI_ERROR(efi_status) || !proto)
+ return efi_status;
+
+ efi_status = get_mem_attrs (addr, size, &before);
+ if (EFI_ERROR(efi_status))
+ dprint(L"get_mem_attrs(0x%llx, 0x%llx, 0x%llx) -> 0x%lx\n",
+ (unsigned long long)addr, (unsigned long long)size,
+ &before, efi_status);
+
+ if (!IS_PAGE_ALIGNED(physaddr) || !IS_PAGE_ALIGNED(size) || size == 0) {
+ perror(L"Invalid call %a(addr:0x%llx-0x%llx, size:0x%llx, +%a%a%a, -%a%a%a)\n",
+ __func__, (unsigned long long)physaddr,
+ (unsigned long long)(physaddr + size - 1),
+ (unsigned long long)size,
+ (set_attrs & MEM_ATTR_R) ? "r" : "",
+ (set_attrs & MEM_ATTR_W) ? "w" : "",
+ (set_attrs & MEM_ATTR_X) ? "x" : "",
+ (clear_attrs & MEM_ATTR_R) ? "r" : "",
+ (clear_attrs & MEM_ATTR_W) ? "w" : "",
+ (clear_attrs & MEM_ATTR_X) ? "x" : "");
+ if (!IS_PAGE_ALIGNED(physaddr))
+ perror(L" addr is not page aligned\n");
+ if (!IS_PAGE_ALIGNED(size))
+ perror(L" size is not page aligned\n");
+ if (size == 0)
+ perror(L" size is 0\n");
+ return 0;
+ }
+
+ uefi_set_attrs = shim_mem_attrs_to_uefi_mem_attrs (set_attrs);
+ dprint("translating set_attrs from 0x%lx to 0x%lx\n", set_attrs, uefi_set_attrs);
+ uefi_clear_attrs = shim_mem_attrs_to_uefi_mem_attrs (clear_attrs);
+ dprint("translating clear_attrs from 0x%lx to 0x%lx\n", clear_attrs, uefi_clear_attrs);
+ efi_status = EFI_SUCCESS;
+ if (uefi_set_attrs) {
+ efi_status = proto->SetMemoryAttributes(proto, physaddr, size, uefi_set_attrs);
+ if (EFI_ERROR(efi_status)) {
+ dprint(L"Failed to set memory attrs:0x%0x physaddr:0x%llx size:0x%0lx status:%r\n",
+ uefi_set_attrs, physaddr, size, efi_status);
+ }
+ }
+ if (!EFI_ERROR(efi_status) && uefi_clear_attrs) {
+ efi_status = proto->ClearMemoryAttributes(proto, physaddr, size, uefi_clear_attrs);
+ if (EFI_ERROR(efi_status)) {
+ dprint(L"Failed to clear memory attrs:0x%0x physaddr:0x%llx size:0x%0lx status:%r\n",
+ uefi_clear_attrs, physaddr, size, efi_status);
+ }
+ }
+ ret = efi_status;
+
+ efi_status = get_mem_attrs (addr, size, &after);
+ if (EFI_ERROR(efi_status))
+ dprint(L"get_mem_attrs(0x%llx, %llu, 0x%llx) -> 0x%lx\n",
+ (unsigned long long)addr, (unsigned long long)size,
+ &after, efi_status);
+
+ dprint(L"set +%a%a%a -%a%a%a on 0x%llx-0x%llx before:%c%c%c after:%c%c%c\n",
+ (set_attrs & MEM_ATTR_R) ? "r" : "",
+ (set_attrs & MEM_ATTR_W) ? "w" : "",
+ (set_attrs & MEM_ATTR_X) ? "x" : "",
+ (clear_attrs & MEM_ATTR_R) ? "r" : "",
+ (clear_attrs & MEM_ATTR_W) ? "w" : "",
+ (clear_attrs & MEM_ATTR_X) ? "x" : "",
+ (unsigned long long)addr, (unsigned long long)(addr + size - 1),
+ (before & MEM_ATTR_R) ? 'r' : '-',
+ (before & MEM_ATTR_W) ? 'w' : '-',
+ (before & MEM_ATTR_X) ? 'x' : '-',
+ (after & MEM_ATTR_R) ? 'r' : '-',
+ (after & MEM_ATTR_W) ? 'w' : '-',
+ (after & MEM_ATTR_X) ? 'x' : '-');
+
+ return ret;
+}
+
+// vim:fenc=utf-8:tw=75:noet
diff --git a/pe.c b/pe.c
index cd80b07d..40812bb7 100644
--- a/pe.c
+++ b/pe.c
@@ -395,158 +395,6 @@ err:
return efi_status;
}
-static inline uint64_t
-shim_mem_attrs_to_uefi_mem_attrs (uint64_t attrs)
-{
- uint64_t ret = EFI_MEMORY_RP |
- EFI_MEMORY_RO |
- EFI_MEMORY_XP;
-
- if (attrs & MEM_ATTR_R)
- ret &= ~EFI_MEMORY_RP;
-
- if (attrs & MEM_ATTR_W)
- ret &= ~EFI_MEMORY_RO;
-
- if (attrs & MEM_ATTR_X)
- ret &= ~EFI_MEMORY_XP;
-
- return ret;
-}
-
-static inline uint64_t
-uefi_mem_attrs_to_shim_mem_attrs (uint64_t attrs)
-{
- uint64_t ret = MEM_ATTR_R |
- MEM_ATTR_W |
- MEM_ATTR_X;
-
- if (attrs & EFI_MEMORY_RP)
- ret &= ~MEM_ATTR_R;
-
- if (attrs & EFI_MEMORY_RO)
- ret &= ~MEM_ATTR_W;
-
- if (attrs & EFI_MEMORY_XP)
- ret &= ~MEM_ATTR_X;
-
- return ret;
-}
-
-static EFI_STATUS
-get_mem_attrs (uintptr_t addr, size_t size, uint64_t *attrs)
-{
- EFI_MEMORY_ATTRIBUTE_PROTOCOL *proto = NULL;
- EFI_PHYSICAL_ADDRESS physaddr = addr;
- EFI_STATUS efi_status;
-
- efi_status = LibLocateProtocol(&EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID,
- (VOID **)&proto);
- if (EFI_ERROR(efi_status) || !proto) {
- if (!EFI_ERROR(efi_status))
- efi_status = EFI_UNSUPPORTED;
- return efi_status;
- }
-
- if (!IS_PAGE_ALIGNED(physaddr) || !IS_PAGE_ALIGNED(size) || size == 0 || attrs == NULL) {
- dprint(L"%a called on 0x%llx-0x%llx and attrs 0x%llx\n",
- __func__, (unsigned long long)physaddr,
- (unsigned long long)(physaddr+size-1),
- attrs);
- return EFI_SUCCESS;
- }
-
- efi_status = proto->GetMemoryAttributes(proto, physaddr, size, attrs);
- *attrs = uefi_mem_attrs_to_shim_mem_attrs (*attrs);
-
- return efi_status;
-}
-
-static EFI_STATUS
-update_mem_attrs(uintptr_t addr, uint64_t size,
- uint64_t set_attrs, uint64_t clear_attrs)
-{
- EFI_MEMORY_ATTRIBUTE_PROTOCOL *proto = NULL;
- EFI_PHYSICAL_ADDRESS physaddr = addr;
- EFI_STATUS efi_status, ret;
- uint64_t before = 0, after = 0, uefi_set_attrs, uefi_clear_attrs;
-
- efi_status = LibLocateProtocol(&EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID,
- (VOID **)&proto);
- if (EFI_ERROR(efi_status) || !proto)
- return efi_status;
-
- efi_status = get_mem_attrs (addr, size, &before);
- if (EFI_ERROR(efi_status))
- dprint(L"get_mem_attrs(0x%llx, 0x%llx, 0x%llx) -> 0x%lx\n",
- (unsigned long long)addr, (unsigned long long)size,
- &before, efi_status);
-
- if (!IS_PAGE_ALIGNED(physaddr) || !IS_PAGE_ALIGNED(size) || size == 0) {
- perror(L"Invalid call %a(addr:0x%llx-0x%llx, size:0x%llx, +%a%a%a, -%a%a%a)\n",
- __func__, (unsigned long long)physaddr,
- (unsigned long long)(physaddr + size - 1),
- (unsigned long long)size,
- (set_attrs & MEM_ATTR_R) ? "r" : "",
- (set_attrs & MEM_ATTR_W) ? "w" : "",
- (set_attrs & MEM_ATTR_X) ? "x" : "",
- (clear_attrs & MEM_ATTR_R) ? "r" : "",
- (clear_attrs & MEM_ATTR_W) ? "w" : "",
- (clear_attrs & MEM_ATTR_X) ? "x" : "");
- if (!IS_PAGE_ALIGNED(physaddr))
- perror(L" addr is not page aligned\n");
- if (!IS_PAGE_ALIGNED(size))
- perror(L" size is not page aligned\n");
- if (size == 0)
- perror(L" size is 0\n");
- return 0;
- }
-
- uefi_set_attrs = shim_mem_attrs_to_uefi_mem_attrs (set_attrs);
- dprint("translating set_attrs from 0x%lx to 0x%lx\n", set_attrs, uefi_set_attrs);
- uefi_clear_attrs = shim_mem_attrs_to_uefi_mem_attrs (clear_attrs);
- dprint("translating clear_attrs from 0x%lx to 0x%lx\n", clear_attrs, uefi_clear_attrs);
- efi_status = EFI_SUCCESS;
- if (uefi_set_attrs) {
- efi_status = proto->SetMemoryAttributes(proto, physaddr, size, uefi_set_attrs);
- if (EFI_ERROR(efi_status)) {
- dprint(L"Failed to set memory attrs:0x%0x physaddr:0x%llx size:0x%0lx status:%r\n",
- uefi_set_attrs, physaddr, size, efi_status);
- }
- }
- if (!EFI_ERROR(efi_status) && uefi_clear_attrs) {
- efi_status = proto->ClearMemoryAttributes(proto, physaddr, size, uefi_clear_attrs);
- if (EFI_ERROR(efi_status)) {
- dprint(L"Failed to clear memory attrs:0x%0x physaddr:0x%llx size:0x%0lx status:%r\n",
- uefi_clear_attrs, physaddr, size, efi_status);
- }
- }
- ret = efi_status;
-
- efi_status = get_mem_attrs (addr, size, &after);
- if (EFI_ERROR(efi_status))
- dprint(L"get_mem_attrs(0x%llx, %llu, 0x%llx) -> 0x%lx\n",
- (unsigned long long)addr, (unsigned long long)size,
- &after, efi_status);
-
- dprint(L"set +%a%a%a -%a%a%a on 0x%llx-0x%llx before:%c%c%c after:%c%c%c\n",
- (set_attrs & MEM_ATTR_R) ? "r" : "",
- (set_attrs & MEM_ATTR_W) ? "w" : "",
- (set_attrs & MEM_ATTR_X) ? "x" : "",
- (clear_attrs & MEM_ATTR_R) ? "r" : "",
- (clear_attrs & MEM_ATTR_W) ? "w" : "",
- (clear_attrs & MEM_ATTR_X) ? "x" : "",
- (unsigned long long)addr, (unsigned long long)(addr + size - 1),
- (before & MEM_ATTR_R) ? 'r' : '-',
- (before & MEM_ATTR_W) ? 'w' : '-',
- (before & MEM_ATTR_X) ? 'x' : '-',
- (after & MEM_ATTR_R) ? 'r' : '-',
- (after & MEM_ATTR_W) ? 'w' : '-',
- (after & MEM_ATTR_X) ? 'x' : '-');
-
- return ret;
-}
-
EFI_STATUS verify_image(void *data, unsigned int datasize,
EFI_LOADED_IMAGE *li,
PE_COFF_LOADER_IMAGE_CONTEXT *context)
diff --git a/shim.h b/shim.h
index f2246c90..59d90629 100644
--- a/shim.h
+++ b/shim.h
@@ -176,6 +176,7 @@
#include "include/ip6config.h"
#include "include/load-options.h"
#include "include/loader-proto.h"
+#include "include/memattrs.h"
#include "include/mok.h"
#include "include/netboot.h"
#include "include/passwordcrypt.h"