Skip to content

Commit

Permalink
Ring3: Added support for USER attribute in .fdf files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Krichanov committed Oct 25, 2024
1 parent c11185c commit 5db269a
Show file tree
Hide file tree
Showing 22 changed files with 107 additions and 75 deletions.
6 changes: 4 additions & 2 deletions ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions BaseTools/Source/C/GenFfs/GenFfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,13 @@ Routine Description:
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");
Expand Down
1 change: 1 addition & 0 deletions BaseTools/Source/Python/CommonDataClass/FdfClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__(self):
self.KeyStringList = []
self.KeepReloc = None
self.UseArch = None
self.User = False

## section data in FDF
#
Expand Down
2 changes: 2 additions & 0 deletions BaseTools/Source/Python/GenFds/FdfParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2500,6 +2500,8 @@ def _GetInfOptions(self, FfsInfObj):
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\))')
Expand Down
6 changes: 4 additions & 2 deletions BaseTools/Source/Python/GenFds/FfsInfStatement.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,8 @@ def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None):
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=SectionAlignments,
MakefilePath=MakefilePath
MakefilePath=MakefilePath,
User=self.User
)
return FfsOutput

Expand Down Expand Up @@ -1072,7 +1073,8 @@ def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None
self.ModuleGuid, Fixed=Rule.Fixed,
CheckSum=Rule.CheckSum, Align=Rule.Alignment,
SectionAlign=Alignments,
MakefilePath=MakefilePath
MakefilePath=MakefilePath,
User=self.User
)
return FfsOutput

Expand Down
4 changes: 3 additions & 1 deletion BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,15 @@ def GetAlignment (AlignString):

@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)
Expand Down
13 changes: 5 additions & 8 deletions MdeModulePkg/Core/Dxe/DxeMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ typedef struct {

VOID *HiiData;
BOOLEAN IsUserImage;
BOOLEAN IsRing3EntryPoint;
} LOADED_IMAGE_PRIVATE_DATA;

typedef struct {
Expand Down Expand Up @@ -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
);

/**
Expand Down
2 changes: 1 addition & 1 deletion MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
35 changes: 20 additions & 15 deletions MdeModulePkg/Core/Dxe/Image/Image.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1108,6 +1107,7 @@ CoreLoadImageCommon (
BOOLEAN ImageIsFromLoadFile;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT8 ImageOrigin;
EFI_FV_FILE_ATTRIBUTES FileAttributes;

SecurityStatus = EFI_SUCCESS;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1209,6 +1210,7 @@ CoreLoadImageCommon (
BootPolicy,
FilePath,
&FHand.SourceSize,
&FileAttributes,
&AuthenticationStatus
);
if (FHand.Source == NULL) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Image->Status = GoToRing3 (
2,
(VOID *)Image->EntryPoint,
ImageHandle,
gRing3Data
);
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
);
}
} else {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
}
Expand Down
29 changes: 7 additions & 22 deletions MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))) {
Expand Down
3 changes: 2 additions & 1 deletion MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,7 @@ BmGetNextLoadOptionBuffer (
EFI_DEVICE_PATH_PROTOCOL *CurFullPath;
UINTN LocalFileSize;
UINT32 AuthenticationStatus;
EFI_FV_FILE_ATTRIBUTES FileAttributes;

LocalFileSize = 0;
FileBuffer = NULL;
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions MdeModulePkg/MdeModulePkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions MdePkg/Include/Library/DxeServicesLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
);

Expand Down
1 change: 1 addition & 0 deletions MdePkg/Include/Pi/PiFirmwareFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions MdePkg/Include/Pi/PiFirmwareVolume.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 5db269a

Please sign in to comment.