diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index df6196a41c..b0b814a780 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -701,6 +701,10 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + + Ebx = 0; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -970,5 +974,21 @@ CreateIdentityMappingPageTables ( EnableExecuteDisableBit (); } + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + return (UINTN)PageMap; } diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 95f805599d..0f4542e8ef 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -6502,6 +6502,24 @@ AsmReadCr4 ( VOID ); +/** + Writes a value to the EFLAGS register. + + Writes and returns a new value to the EFLAGS register. This function is + only available on IA-32 and x64. This writes a 32-bit value on IA-32 and + a 64-bit value on x64. + + @param EFLAGS The value to write to EFLAGS. + + @return The value written to EFLAGS. + +**/ +UINTN +EFIAPI +AsmWriteEflags ( + UINTN Eflags + ); + /** Writes a value to Control Register 0 (CR0). diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 26e66a8d67..dff5ca56af 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -294,6 +294,7 @@ X64/ReadCr2.nasm| MSFT X64/ReadCr0.nasm| MSFT X64/ReadEflags.nasm| MSFT + X64/WriteEflags.nasm X64/TdCall.nasm X64/TdVmcall.nasm diff --git a/MdePkg/Library/BaseLib/X64/WriteEflags.nasm b/MdePkg/Library/BaseLib/X64/WriteEflags.nasm new file mode 100644 index 0000000000..85866a9899 --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/WriteEflags.nasm @@ -0,0 +1,33 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +; Module Name: +; +; WriteEflags.Asm +; +; Abstract: +; +; AsmWriteEflags function +; +; Notes: +; +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteEflags ( +; UINTN Eflags +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmWriteEflags) +ASM_PFX(AsmWriteEflags): + push rcx + popfq + mov rax, rcx + ret