Skip to content

Commit

Permalink
post-process-pe: set EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT
Browse files Browse the repository at this point in the history
Currently, system firmware has no means to discover that an EFI
Application is compatible with the security feature variously known as
NX or w^x.

Since at least Revision 8.1, the PE spec supports setting a flag the
Optional Header's DllCharacteristics field to inform loaders that an
application supports being loaded with NX enabled.

In the case of UEFI, there are several things that should be enabled if
this flag is set:

- EFI_BOOT_SERVICES.AllocatePages() with MemoryType = EfiLoaderCode,
  EfiBootServicesCode, EfiRuntimeServicesCode, etc, currently must set
  memory as rwx.  This flag set implies that rw- is appropriate, and
  that the application knows how to use the EFI_MEMORY_ATTRIBUTE
  protocol to change that to r-x.
- EFI_BOOT_SERVICES.AllocatePool() - same as AllocatePages()
- EFI_BOOT_SERVICES.LoadImage()
  - currently must set the stack as rwx. This flag states that it is
    allowed to be rw-
  - currently a binary can probably have writable PLTs?  This flag
    allows the loader to not set them writable
- I have heard that some firmwares have the 0 page mapped rwx.
  Obviously this should not be done.

Signed-off-by: Peter Jones <pjones@redhat.com>
  • Loading branch information
vathpela committed Apr 12, 2022
1 parent 9d1f6a5 commit 82e7d5b
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions post-process-pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,30 @@ load_pe(const char *const file, void *const data, const size_t datasize,
errx(1, "%s: Security directory extends past end", file);
}

static void
set_dll_characteristics(PE_COFF_LOADER_IMAGE_CONTEXT *ctx)
{
uint16_t oldflags, newflags;

if (image_is_64_bit(ctx->PEHdr)) {
oldflags = ctx->PEHdr->Pe32Plus.OptionalHeader.DllCharacteristics;
} else {
oldflags = ctx->PEHdr->Pe32.OptionalHeader.DllCharacteristics;
}

newflags = oldflags | EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
if (oldflags == newflags)
return;

debug(INFO, "Updating DLL Characteristics from 0x%04hx to 0x%04hx\n",
oldflags, newflags);
if (image_is_64_bit(ctx->PEHdr)) {
ctx->PEHdr->Pe32Plus.OptionalHeader.DllCharacteristics = newflags;
} else {
ctx->PEHdr->Pe32.OptionalHeader.DllCharacteristics = newflags;
}
}

static void
fix_timestamp(PE_COFF_LOADER_IMAGE_CONTEXT *ctx)
{
Expand Down Expand Up @@ -417,6 +441,8 @@ handle_one(char *f)

load_pe(f, map, sz, &ctx);

set_dll_characteristics(&ctx);

fix_timestamp(&ctx);

fix_checksum(&ctx, map, sz);
Expand Down

0 comments on commit 82e7d5b

Please sign in to comment.