diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index c2770575de..057904e427 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -289,8 +289,6 @@ extern VOID *gCoreSysCallStackTop; extern VOID *gRing3CallStackBase; extern VOID *gRing3CallStackTop; extern VOID *gRing3EntryPoint; -extern VOID *gUserPageTableTemplate; -extern UINTN gUserPageTableTemplateSize; extern UINTN gUserPageTable; extern UINTN gCorePageTable; @@ -2650,18 +2648,9 @@ UnprotectUefiImage ( IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath ); -/** - Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[in] IsUser Whether UEFI image record is User Image. -**/ -VOID -ChangeUefiImageRing ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, - IN BOOLEAN IsUser +UEFI_IMAGE_RECORD * +GetUefiImageRecord ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ); /** @@ -2728,6 +2717,18 @@ SetUefiImageMemoryAttributes ( IN UINT64 Attributes ); +/** + Set UEFI image protection attributes. + + @param[in] ImageRecord A UEFI image record + @param[in] IsUser Whether UEFI image record is User Image. +**/ +VOID +SetUefiImageProtectionAttributes ( + IN UEFI_IMAGE_RECORD *ImageRecord, + IN BOOLEAN IsUser + ); + EFI_STATUS EFIAPI CoreBootServices ( @@ -2782,10 +2783,10 @@ FreeProtocolsList ( VOID ); -VOID +UINTN EFIAPI -MakeUserPageTableTemplate ( - VOID +InitializeUserPageTable ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ); #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 8c69e4da29..ca7e4f4d3b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -246,7 +246,7 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfo; gRing3Data = NULL; - + // // Setup Stack Guard // @@ -328,8 +328,6 @@ DxeMain ( ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage); - MakeUserPageTableTemplate (); - // // Call constructor for all libraries // diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 575fa12788..b63e55ccdb 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1108,7 +1108,6 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; - VOID *UserPageTable; SecurityStatus = EFI_SUCCESS; @@ -1349,14 +1348,6 @@ CoreLoadImageCommon ( Image->Info.ParentHandle = ParentImageHandle; Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; - if ((gRing3Data != NULL) && Image->IsUserImage) { - UserPageTable = AllocatePages (EFI_SIZE_TO_PAGES (gUserPageTableTemplateSize)); - CopyMem (UserPageTable, gUserPageTableTemplate, gUserPageTableTemplateSize); - - Image->UserPageTable = (UINTN)UserPageTable; - gUserPageTable = Image->UserPageTable; - } - if (NumberOfPages != NULL) { Image->NumberOfPages = *NumberOfPages; } else { @@ -1453,6 +1444,11 @@ CoreLoadImageCommon ( Status = EFI_SUCCESS; ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); + if ((gRing3Data != NULL) && Image->IsUserImage) { + Image->UserPageTable = InitializeUserPageTable (Image); + gUserPageTable = Image->UserPageTable; + } + RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, (UefiImageGetSubsystem (&ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER), diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index d9ada48738..1066a148bc 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -82,10 +82,6 @@ SetUefiImageMemoryAttributes ( ASSERT (gCpu != NULL); gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes); - - if ((Attributes & EFI_MEMORY_USER) != 0) { - gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, BaseAddress, Length, FinalAttributes); - } } /** @@ -291,22 +287,13 @@ UnprotectUefiImage ( } } -/** - Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[in] IsUser Whether UEFI image record is User Image. -**/ -VOID -ChangeUefiImageRing ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, - IN BOOLEAN IsUser +UEFI_IMAGE_RECORD * +GetUefiImageRecord ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ) { - UEFI_IMAGE_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; ImageRecordLink != &mProtectedImageRecordList; @@ -319,14 +306,12 @@ ChangeUefiImageRing ( UEFI_IMAGE_RECORD_SIGNATURE ); - if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { - ASSERT (gCpu != NULL); - - SetUefiImageProtectionAttributes (ImageRecord, IsUser); - - return; + if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Image->Info.ImageBase) { + return ImageRecord; } } + + return NULL; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index dd2c9ccea3..dc80c10f4b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,6 +18,17 @@ RING3_DATA *gRing3Data; VOID *gRing3Interfaces; UINTN gUartBaseAddress; +UEFI_IMAGE_RECORD *mDxeRing3; +VOID *mUserPageTableTemplate; +UINTN mUserPageTableTemplateSize; + +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ); + VOID EFIAPI InitializeMsr ( @@ -102,11 +113,14 @@ InitializeRing3 ( // // Initialize DxeRing3 with Supervisor privileges. // - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); + mDxeRing3 = GetUefiImageRecord (Image); + ASSERT (mDxeRing3 != NULL); + + SetUefiImageProtectionAttributes (mDxeRing3, FALSE); Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); + SetUefiImageProtectionAttributes (mDxeRing3, TRUE); gRing3EntryPoint = gRing3Data->EntryPoint; @@ -153,9 +167,6 @@ InitializeRing3 ( gCoreSysCallStackTop = TopOfStack; SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - // - // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - // DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // @@ -180,5 +191,124 @@ InitializeRing3 ( gRing3Data->SystemTable.NumberOfTableEntries ); + MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize); + return Status; } + +UINTN +EFIAPI +InitializeUserPageTable ( + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + UINTN UserPageTable; + UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; + UINTN SectionAddress; + UINT32 Index; + UEFI_IMAGE_RECORD *UserImageRecord; + + UserPageTable = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (mUserPageTableTemplateSize)); + + CopyMem ((VOID *)UserPageTable, mUserPageTableTemplate, mUserPageTableTemplateSize); + + // + // Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3Data, + ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3Interfaces, + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3CallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + SectionAddress = mDxeRing3->StartAddress; + for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { + ImageRecordSegment = &mDxeRing3->Segments[Index]; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); + + SectionAddress += ImageRecordSegment->Size; + } + + // + // Map CoreBootServices + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, + SIZE_4KB, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (EFI_PHYSICAL_ADDRESS)(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, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + // + // Map User Image + // + UserImageRecord = GetUefiImageRecord (Image); + ASSERT (UserImageRecord != NULL); + + SectionAddress = UserImageRecord->StartAddress; + for (Index = 0; Index < UserImageRecord->NumSegments; Index++) { + ImageRecordSegment = &UserImageRecord->Segments[Index]; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); + + SectionAddress += ImageRecordSegment->Size; + } + + return UserPageTable; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 7c0b84783f..fd7f39ef39 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -10,13 +10,11 @@ #include #include -VOID *gUserPageTableTemplate; -UINTN gUserPageTableTemplateSize; - VOID EFIAPI MakeUserPageTableTemplate ( - VOID + OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize ) { EFI_HOB_GUID_TYPE *GuidHob; @@ -167,42 +165,10 @@ MakeUserPageTableTemplate ( ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } - gUserPageTableTemplate = (VOID *)PageMap; - gUserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - gUserPageTable = (UINTN)gUserPageTableTemplate; + *UserPageTableTemplate = (VOID *)PageMap; + *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - SetUefiImageMemoryAttributes ((UINT64)PageMap, gUserPageTableTemplateSize, EFI_MEMORY_XP); - // - // Map CoreBootServices - // - gCpu->SetUserMemoryAttributes ( - gCpu, - (UINTN)PageMap, - (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, - SIZE_4KB, - EFI_MEMORY_RO - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - (UINTN)PageMap, - (EFI_PHYSICAL_ADDRESS)(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, - (UINTN)PageMap, - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + SetUefiImageMemoryAttributes ((UINT64)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); } VOID