Currently, we rely on the memory type for loading images being executable by default, and only restrict the permissions if the policy says so, and the image sections are suitably aligned. This requires that the various 'code' memory types are executable by default, which is unfortunate.
In order to be able to tighten this, let's update the image protection policy handling so that images that should not be mapped with strict separation of RW- and R-X are remapped RWX explicitly if the memory type used for loading the images is marked as NX by default. Signed-off-by: Ard Biesheuvel <a...@kernel.org> --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 98 +++++++++++--------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 301ddd6eb053..7c7a946c1b48 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -373,11 +373,62 @@ ProtectUefiImage ( } ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath); + + ImageAddress = LoadedImage->ImageBase; + + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); + } + switch (ProtectionPolicy) { - case DO_NOT_PROTECT: - return EFI_SUCCESS; case PROTECT_IF_ALIGNED_ELSE_ALLOW: - break; + // + // Check PE/COFF image + // + DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress; + PeCoffHeaderOffset = 0; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + PeCoffHeaderOffset = DosHdr->e_lfanew; + } + + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); + if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { + DEBUG ((DEBUG_INFO, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); + // It might be image in SMM. + } else { + // + // Get SectionAlignment + // + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; + } else { + SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; + } + + if (SectionAlignment >= EFI_PAGE_SIZE) { + break; + } + + DEBUG (( + DEBUG_VERBOSE, + "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n", + SectionAlignment + )); + } + // fall through to unprotect image if needed + case DO_NOT_PROTECT: + if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & + LShiftU64 (1, LoadedImage->ImageCodeType)) != 0) + { + SetUefiImageMemoryAttributes ( + (UINTN)LoadedImage->ImageBase, + (LoadedImage->ImageSize + EFI_PAGE_MASK) & ~(UINT64)EFI_PAGE_MASK, + 0 + ); + } + + return EFI_SUCCESS; default: ASSERT (FALSE); return EFI_SUCCESS; @@ -396,47 +447,6 @@ ProtectUefiImage ( ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase; ImageRecord->ImageSize = LoadedImage->ImageSize; - ImageAddress = LoadedImage->ImageBase; - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); - } - - // - // Check PE/COFF image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); - // It might be image in SMM. - goto Finish; - } - - // - // Get SectionAlignment - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; - } else { - SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; - } - - if (SectionAlignment >= EFI_PAGE_SIZE) { - DEBUG (( - DEBUG_VERBOSE, - "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n", - SectionAlignment - )); - goto Finish; - } - Section = (EFI_IMAGE_SECTION_HEADER *)( (UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset + -- 2.39.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#101139): https://edk2.groups.io/g/devel/message/101139 Mute This Topic: https://groups.io/mt/97586058/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-