Ring3: Added support for USER attribute in .fdf files.

This commit is contained in:
Mikhail Krichanov 2024-10-25 12:02:51 +03:00
parent c11185cb8c
commit 5db269aab4
22 changed files with 106 additions and 74 deletions

View File

@ -40,6 +40,8 @@ READ_LOCK_STATUS = TRUE
APRIORI DXE {
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
# The driver responsible for UserSpace initialization (DxeRing3.inf)
# must be the first USER driver in APRIORI list.
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
}
@ -86,8 +88,8 @@ APRIORI DXE {
#
INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

View File

@ -592,6 +592,13 @@ Returns:
continue;
}
if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--user") == 0)) {
FfsAttrib |= FFS_ATTRIB_USER;
argc -= 1;
argv += 1;
continue;
}
if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {
if (argv[1] == NULL || argv[1][0] == '-') {
Error (NULL, 0, 1003, "Invalid option value", "Align value is missing for -a option");

View File

@ -81,6 +81,7 @@ class FfsInfStatementClassObject(FfsClassObject):
self.KeyStringList = []
self.KeepReloc = None
self.UseArch = None
self.User = False
## section data in FDF
#

View File

@ -2500,6 +2500,8 @@ class FdfParser:
raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)
FfsInfObj.UseArch = self._Token
if self._IsKeyword("USER"):
FfsInfObj.User = True
if self._GetNextToken():
p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')

View File

@ -899,7 +899,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=SectionAlignments,
MakefilePath=MakefilePath
MakefilePath=MakefilePath,
User=self.User
)
return FfsOutput
@ -1072,7 +1073,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=Alignments,
MakefilePath=MakefilePath
MakefilePath=MakefilePath,
User=self.User
)
return FfsOutput

View File

@ -535,13 +535,15 @@ class GenFdsGlobalVariable:
@staticmethod
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
SectionAlign=None, MakefilePath=None):
SectionAlign=None, MakefilePath=None, User=False):
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
if Fixed == True:
Cmd.append("-x")
if CheckSum:
Cmd.append("-s")
if User:
Cmd.append("-u")
if Align:
if Align not in mFfsValidAlign:
Align = GenFdsGlobalVariable.GetAlignment (Align)

View File

@ -229,7 +229,6 @@ typedef struct {
VOID *HiiData;
BOOLEAN IsUserImage;
BOOLEAN IsRing3EntryPoint;
} LOADED_IMAGE_PRIVATE_DATA;
typedef struct {
@ -2624,16 +2623,14 @@ RemoveImageRecord (
@param[in] LoadedImage The loaded image protocol
@param[in] ImageOrigin Where File comes from.
@param[in] LoadedImageDevicePath The loaded image device path protocol
@param[out] IsUserImage Whether the loaded image is in user space.
@param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls.
@param[in] IsUserImage Whether the loaded image is in user space.
**/
VOID
ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT BOOLEAN *IsUserImage,
OUT BOOLEAN *IsRing3EntryPoint
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN BOOLEAN IsUserImage
);
/**

View File

@ -326,7 +326,7 @@ DxeMain (
CoreInitializeMemoryProtection ();
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage, &mCurrentImage->IsRing3EntryPoint);
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage);
//
// Call constructor for all libraries

View File

@ -61,6 +61,10 @@ FfsAttributes2FvFileAttributes (
FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;
}
if ((FfsAttributes & FFS_ATTRIB_USER) == FFS_ATTRIB_USER) {
FileAttribute |= EFI_FV_FILE_ATTRIB_USER;
}
return FileAttribute;
}

View File

@ -67,8 +67,7 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
NULL, // LoadedImageDevicePath
EFI_SUCCESS, // LoadImageStatus
NULL, // HiiData
FALSE, // IsUserImage
FALSE // IsRing3EntryPoint
FALSE // IsUserImage
};
//
// The field is define for Loading modules at fixed address feature to tracker the PEI code
@ -1108,6 +1107,7 @@ CoreLoadImageCommon (
BOOLEAN ImageIsFromLoadFile;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT8 ImageOrigin;
EFI_FV_FILE_ATTRIBUTES FileAttributes;
SecurityStatus = EFI_SUCCESS;
@ -1138,6 +1138,7 @@ CoreLoadImageCommon (
AuthenticationStatus = 0;
ImageIsFromFv = FALSE;
ImageIsFromLoadFile = FALSE;
FileAttributes = 0;
//
// If the caller passed a copy of the file, then just use it
@ -1209,6 +1210,7 @@ CoreLoadImageCommon (
BootPolicy,
FilePath,
&FHand.SourceSize,
&FileAttributes,
&AuthenticationStatus
);
if (FHand.Source == NULL) {
@ -1344,6 +1346,7 @@ CoreLoadImageCommon (
Image->Info.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
Image->Info.FilePath = DuplicateDevicePath (FilePath);
Image->Info.ParentHandle = ParentImageHandle;
Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0;
if (NumberOfPages != NULL) {
Image->NumberOfPages = *NumberOfPages;
@ -1439,7 +1442,7 @@ CoreLoadImageCommon (
}
Status = EFI_SUCCESS;
ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage, &Image->IsRing3EntryPoint);
ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage);
RegisterMemoryProfileImage (
Image->LoadedImageDevicePath,
@ -1689,18 +1692,20 @@ CoreStartImage (
//
Image->Started = TRUE;
if (Image->IsRing3EntryPoint) {
Image->Status = InitializeRing3 (ImageHandle, Image);
} else if (Image->IsUserImage) {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) {
if (gRing3Data == NULL) {
Image->Status = InitializeRing3 (ImageHandle, Image);
} else {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
Image->Status = GoToRing3 (
2,
(VOID *)Image->EntryPoint,
ImageHandle,
gRing3Data
);
Image->Status = GoToRing3 (
2,
(VOID *)Image->EntryPoint,
ImageHandle,
gRing3Data
);
}
} else {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
}

View File

@ -166,16 +166,14 @@ IsMemoryProtectionSectionAligned (
@param[in] LoadedImage The loaded image protocol
@param[in] ImageOrigin Where File comes from.
@param[in] LoadedImageDevicePath The loaded image device path protocol
@param[out] IsUserImage Whether the loaded image is in user space.
@param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls.
@param[in] IsUserImage Whether the loaded image is in user space.
**/
VOID
ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT BOOLEAN *IsUserImage,
OUT BOOLEAN *IsRing3EntryPoint
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN BOOLEAN IsUserImage
)
{
RETURN_STATUS PdbStatus;
@ -230,27 +228,14 @@ ProtectUefiImage (
//
InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link);
*IsRing3EntryPoint = FALSE;
if (gCpu != NULL) {
//
// CPU ARCH present. Update memory attribute directly.
//
if (PcdGetBool (PcdEnableUserSpace) && (!RETURN_ERROR (PdbStatus))) {
if (AsciiStrStr (PdbPointer, "Fat") != NULL) {
SetUefiImageProtectionAttributes (ImageRecord, TRUE);
*IsUserImage = TRUE;
} else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) {
SetUefiImageProtectionAttributes (ImageRecord, TRUE);
*IsUserImage = TRUE;
*IsRing3EntryPoint = TRUE;
} else {
SetUefiImageProtectionAttributes (ImageRecord, FALSE);
*IsUserImage = FALSE;
}
if (PcdGetBool (PcdEnableUserSpace)) {
SetUefiImageProtectionAttributes (ImageRecord, IsUserImage);
} else {
SetUefiImageProtectionAttributes (ImageRecord, FALSE);
*IsUserImage = FALSE;
}
}

View File

@ -221,6 +221,7 @@ ExecuteSecurityHandlers (
EFI_HANDLE Handle;
EFI_DEVICE_PATH_PROTOCOL *Node;
EFI_DEVICE_PATH_PROTOCOL *FilePathToVerfiy;
EFI_FV_FILE_ATTRIBUTES FileAttributes;
if (FilePath == NULL) {
return EFI_INVALID_PARAMETER;
@ -252,12 +253,12 @@ ExecuteSecurityHandlers (
//
// Try to get image by FALSE boot policy for the exact boot file path.
//
FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &AuthenticationStatus);
FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &FileAttributes, &AuthenticationStatus);
if (FileBuffer == NULL) {
//
// Try to get image by TRUE boot policy for the inexact boot file path.
//
FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &AuthenticationStatus);
FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &FileAttributes, &AuthenticationStatus);
}
if ((FileBuffer != NULL) && (!EFI_ERROR (Status))) {

View File

@ -1246,6 +1246,7 @@ BmGetNextLoadOptionBuffer (
EFI_DEVICE_PATH_PROTOCOL *CurFullPath;
UINTN LocalFileSize;
UINT32 AuthenticationStatus;
EFI_FV_FILE_ATTRIBUTES FileAttributes;
LocalFileSize = 0;
FileBuffer = NULL;
@ -1264,7 +1265,7 @@ BmGetNextLoadOptionBuffer (
break;
}
FileBuffer = GetFileBufferByFilePath (TRUE, CurFullPath, &LocalFileSize, &AuthenticationStatus);
FileBuffer = GetFileBufferByFilePath (TRUE, CurFullPath, &LocalFileSize, &FileAttributes, &AuthenticationStatus);
} while (FileBuffer == NULL);
if (FileBuffer == NULL) {

View File

@ -1156,8 +1156,8 @@
# @Prompt Delay access XHCI register after it issues HCRST (us)
gEfiMdeModulePkgTokenSpaceGuid.PcdDelayXhciHCReset|2000|UINT16|0x30001060
## Indicates whether some DXE drivers will be loaded in user memory.
# TRUE - Some DXE drivers will be loaded in user memory.<BR>
## Indicates whether DXE drivers marked in .fdf file as USER will be loaded in user memory.
# TRUE - USER DXE drivers will be loaded in user memory.<BR>
# FALSE - All DXE drivers will be loaded in supervisor memory.<BR>
# @Prompt Enable User Space.
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001061

View File

@ -230,6 +230,7 @@ GetSectionFromFfs (
@param[in] FilePath Pointer to the device path of the file that is abstracted to
the file buffer.
@param[out] FileSize Pointer to the size of the abstracted file buffer.
@param[out] FileAttributes Pointer to the attributes of the file that is abstracted to the file buffer.
@param[out] AuthenticationStatus Pointer to the authentication status.
@retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found.
@ -241,6 +242,7 @@ GetFileBufferByFilePath (
IN BOOLEAN BootPolicy,
IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT UINTN *FileSize,
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
OUT UINT32 *AuthenticationStatus
);

View File

@ -88,6 +88,7 @@ typedef UINT8 EFI_FFS_FILE_STATE;
#define FFS_ATTRIB_FIXED 0x04
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
#define FFS_ATTRIB_CHECKSUM 0x40
#define FFS_ATTRIB_USER 0x80
///
/// FFS File State Bits.

View File

@ -23,6 +23,7 @@ typedef UINT32 EFI_FV_FILE_ATTRIBUTES;
#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F
#define EFI_FV_FILE_ATTRIB_FIXED 0x00000100
#define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200
#define EFI_FV_FILE_ATTRIB_USER 0x00000400
///
/// type of EFI FVB attribute

View File

@ -565,6 +565,7 @@ GetSectionFromFfs (
that is abstracted to the file buffer.
@param[out] FileSize The pointer to the size of the abstracted
file buffer.
@param[out] FileAttributes Pointer to the attributes of the file that is abstracted to the file buffer.
@param[out] AuthenticationStatus Pointer to the authentication status.
@retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found.
@ -576,6 +577,7 @@ GetFileBufferByFilePath (
IN BOOLEAN BootPolicy,
IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT UINTN *FileSize,
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
OUT UINT32 *AuthenticationStatus
)
{
@ -589,7 +591,6 @@ GetFileBufferByFilePath (
UINT8 *ImageBuffer;
UINTN ImageBufferSize;
EFI_FV_FILETYPE Type;
EFI_FV_FILE_ATTRIBUTES Attrib;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
EFI_FILE_HANDLE FileHandle;
EFI_FILE_HANDLE LastHandle;
@ -646,15 +647,26 @@ GetFileBufferByFilePath (
if (!EFI_ERROR (Status)) {
SectionType = EFI_SECTION_PE32;
ImageBuffer = NULL;
Status = FwVol->ReadSection (
FwVol,
FvNameGuid,
SectionType,
0,
(VOID **)&ImageBuffer,
&ImageBufferSize,
AuthenticationStatus
);
Status = FwVol->ReadFile (
FwVol,
FvNameGuid,
NULL,
&ImageBufferSize,
&Type,
FileAttributes,
AuthenticationStatus
);
Status = FwVol->ReadSection (
FwVol,
FvNameGuid,
SectionType,
0,
(VOID **)&ImageBuffer,
&ImageBufferSize,
AuthenticationStatus
);
if (EFI_ERROR (Status)) {
//
// Try a raw file, since a PE32 SECTION does not exist
@ -671,7 +683,7 @@ GetFileBufferByFilePath (
(VOID **)&ImageBuffer,
&ImageBufferSize,
&Type,
&Attrib,
FileAttributes,
AuthenticationStatus
);
}

View File

@ -581,6 +581,8 @@
#
# Security measures for memory protection.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
!if $(LEGACY_WINDOWS_LOADER) == TRUE
# Allow execution of EfiLoaderData memory regions.
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1
@ -593,9 +595,8 @@
# Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions.
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
#
# Firmware volume supports UE, and may require PE.

View File

@ -203,6 +203,8 @@ APRIORI DXE {
!if $(SMM_REQUIRE) == FALSE
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
!endif
# The driver responsible for UserSpace initialization (DxeRing3.inf)
# must be the first USER driver in APRIORI list.
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
}
@ -289,8 +291,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

View File

@ -204,6 +204,8 @@ APRIORI DXE {
!if $(SMM_REQUIRE) == FALSE
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
!endif
# The driver responsible for UserSpace initialization (DxeRing3.inf)
# must be the first USER driver in APRIORI list.
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
}
@ -290,8 +292,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

View File

@ -232,6 +232,8 @@ APRIORI DXE {
!if $(SMM_REQUIRE) == FALSE
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
!endif
# The driver responsible for UserSpace initialization (DxeRing3.inf)
# must be the first USER driver in APRIORI list.
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
}
@ -319,8 +321,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF USER FatPkg/EnhancedFatDxe/Fat.inf
INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf