From 70b97bff7cdb3d7570b1ad173bd206cdd1ef2043 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 27 Nov 2024 18:03:30 +0300 Subject: [PATCH] Ring3: Added necessary Core pages to User page table. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 3 +- .../Core/Dxe/SysCall/Initialization.c | 63 ++++++++++++++----- .../Core/Dxe/SysCall/SupportedProtocols.c | 23 +------ .../Dxe/SysCall/X64/CoreBootServices.nasm | 11 +++- .../Include/Library/CpuExceptionHandlerLib.h | 14 +++++ .../CpuExceptionHandlerLib/DxeException.c | 28 +++++++++ .../X64/ExceptionHandlerAsm.nasm | 35 ++++++++++- 7 files changed, 135 insertions(+), 42 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 1066a148bc..2a271bf889 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -297,8 +297,7 @@ GetUefiImageRecord ( for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; ImageRecordLink != &mProtectedImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) - { + ImageRecordLink = ImageRecordLink->ForwardLink) { ImageRecord = CR ( ImageRecordLink, UEFI_IMAGE_RECORD, diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index dc80c10f4b..f717ae720d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,9 +18,13 @@ RING3_DATA *gRing3Data; VOID *gRing3Interfaces; UINTN gUartBaseAddress; -UEFI_IMAGE_RECORD *mDxeRing3; -VOID *mUserPageTableTemplate; -UINTN mUserPageTableTemplateSize; +UEFI_IMAGE_RECORD *mDxeRing3; +VOID *mUserPageTableTemplate; +UINTN mUserPageTableTemplateSize; +EXCEPTION_ADDRESSES *mExceptionAddresses; + +extern UINTN SysCallBase; +extern UINTN SysCallEnd; VOID EFIAPI @@ -193,6 +197,8 @@ InitializeRing3 ( MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize); + mExceptionAddresses = GetExceptionAddresses (); + return Status; } @@ -255,32 +261,59 @@ InitializeUserPageTable ( } // - // Map CoreBootServices + // Map CoreBootServices, gCoreSysCallStackBase, ExceptionHandlers, ExceptionStacks // gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, - SIZE_4KB, + (UINTN)&SysCallBase, + (UINTN)&SysCallEnd - (UINTN)&SysCallBase, EFI_MEMORY_RO ); gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable, + (UINTN)&gCorePageTable, SIZE_4KB, EFI_MEMORY_RO | EFI_MEMORY_XP ); - // - // Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap - // mCorePageTable, gCoreSysCallStackTop - // - // gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO); - // - // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gCoreSysCallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionHandlerBase, + mExceptionAddresses->ExceptionHandlerSize, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionDataBase, + SIZE_4KB, + EFI_MEMORY_XP + ); + + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 52fb93ff81..4ef2f87fb8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -62,18 +62,7 @@ GoToRing3 ( VA_END (Marker); ForbidSupervisorAccessToUserMemory (); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - } -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) +#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) // // Necessary fix for DEBUG printings. // @@ -85,15 +74,7 @@ GoToRing3 ( #endif Status = CallRing3 (Input); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP - ); - } -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) +#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) AllowSupervisorAccessToUserMemory (); SetUefiImageMemoryAttributes ( gUartBaseAddress, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 8a36fd849b..241c35df0a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -106,6 +106,10 @@ copy: mov gs, ax %endmacro +ALIGN 4096 +global ASM_PFX(SysCallBase) +ASM_PFX(SysCallBase): + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI @@ -123,8 +127,6 @@ copy: ; ; (On User Stack) Argument 4, 5, ... ;------------------------------------------------------------------------------ -ALIGN 4096 - global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): mov rax, [ASM_PFX(gCorePageTable)] @@ -233,6 +235,10 @@ ASM_PFX(CallRing3): ; Pass control to user image o64 sysret +ALIGN 4096 +global ASM_PFX(SysCallEnd) +ASM_PFX(SysCallEnd): + ;------------------------------------------------------------------------------ ; VOID ; EFIAPI @@ -267,5 +273,6 @@ global ASM_PFX(gUserPageTable) ASM_PFX(gUserPageTable): resq 1 +ALIGN 4096 ASM_PFX(CoreRsp): resq 1 diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h index 94e9b20ae1..6864d8cb6c 100644 --- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h +++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h @@ -13,6 +13,14 @@ #include #include +typedef struct { + UINTN ExceptionStackBase; + UINTN ExceptionStackSize; + UINTN ExceptionHandlerBase; + UINTN ExceptionHandlerSize; + UINTN ExceptionDataBase; +} EXCEPTION_ADDRESSES; + /** Initializes all CPU exceptions entries and provides the default exception handlers. @@ -99,4 +107,10 @@ DumpCpuContext ( IN EFI_SYSTEM_CONTEXT SystemContext ); +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ); + #endif diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index 30731a8071..91c2411e4c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -30,6 +30,13 @@ UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE STATIC CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTable = NULL; +EXCEPTION_ADDRESSES mAddresses; + +extern UINTN ExceptionHandlerBase; +extern UINTN ExceptionHandlerEnd; +extern UINT8 mSwitchCr3Flag; +extern UINTN CorePageTable; + /** Common exception handler. @@ -129,13 +136,17 @@ InitializeSeparateExceptionStacks ( UINTN LocalBufferSize; EFI_STATUS Status; + mAddresses.ExceptionStackSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE; + if ((Buffer == NULL) && (BufferSize == NULL)) { SetMem (mBuffer, sizeof (mBuffer), 0); LocalBufferSize = sizeof (mBuffer); Status = ArchSetupExceptionStack (mBuffer, &LocalBufferSize); ASSERT_EFI_ERROR (Status); + mAddresses.ExceptionStackBase = (UINTN)mBuffer; return Status; } else { + mAddresses.ExceptionStackBase = (UINTN)Buffer; return ArchSetupExceptionStack (Buffer, BufferSize); } } @@ -189,3 +200,20 @@ GetImageInfoByIp ( return FALSE; } + +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ) +{ + mSwitchCr3Flag = 1; + + mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; + mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; + mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; + + CorePageTable = AsmReadCr3 (); + + return &mAddresses; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 81d86fb533..49f6267982 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -53,11 +53,27 @@ extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) SECTION .data +ALIGN 4096 + +global ASM_PFX(CorePageTable) +ASM_PFX(CorePageTable): + resq 1 + +global ASM_PFX(UserPageTable) +ASM_PFX(UserPageTable): + resq 1 + +ALIGN 4096 +global ASM_PFX(mSwitchCr3Flag) +ASM_PFX(mSwitchCr3Flag): + db 0x0 DEFAULT REL SECTION .text -ALIGN 8 +ALIGN 4096 +global ASM_PFX(ExceptionHandlerBase) +ASM_PFX(ExceptionHandlerBase): ; Generate NUM_VECTORS IDT vectors. AsmIdtVectorBegin: @@ -121,6 +137,14 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli + cmp byte [ASM_PFX(mSwitchCr3Flag)], 0 + jz NoCr3Switch + mov rax, cr3 + mov [ASM_PFX(UserPageTable)], rax + mov rax, [ASM_PFX(CorePageTable)] + mov cr3, rax + +NoCr3Switch: pop rax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -436,8 +460,8 @@ CetDone: push rcx mov rcx, ds and rcx, 3 - pop rcx jnz ReturnToRing3 + pop rcx mov rsp, rbp pop rbp @@ -466,11 +490,18 @@ DoReturn: DoIret: iretq ReturnToRing3: + mov rcx, [ASM_PFX(UserPageTable)] + mov cr3, rcx + pop rcx mov rsp, rbp pop rbp add rsp, 16 iretq +ALIGN 4096 +global ASM_PFX(ExceptionHandlerEnd) +ASM_PFX(ExceptionHandlerEnd): + ;------------------------------------------------------------------------------------- ; GetTemplateAddressMap (&AddressMap); ;-------------------------------------------------------------------------------------