SysCall: Refactored UserStackTop to allocate it anew for each CallRing3.

This commit is contained in:
Mikhail Krichanov 2025-01-24 18:44:34 +03:00
parent fd4fbf2a26
commit b01769d4c0
5 changed files with 54 additions and 80 deletions

View File

@ -231,14 +231,12 @@ typedef struct {
VOID *HiiData; VOID *HiiData;
BOOLEAN IsUserImage; BOOLEAN IsUserImage;
UINTN UserPageTable; UINTN UserPageTable;
UINTN UserStackTop;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
typedef struct { typedef struct {
VOID *CoreWrapper; VOID *CoreWrapper;
VOID *UserSpaceDriver; VOID *UserSpaceDriver;
UINTN UserPageTable; UINTN UserPageTable;
UINTN UserStackTop;
UINT8 NumberOfCalls; UINT8 NumberOfCalls;
LIST_ENTRY Link; LIST_ENTRY Link;
} USER_SPACE_DRIVER; } USER_SPACE_DRIVER;
@ -2790,9 +2788,7 @@ FreeProtocolsList (
UINTN UINTN
EFIAPI EFIAPI
InitializeUserPageTable ( InitializeUserPageTable (
IN LOADED_IMAGE_PRIVATE_DATA *Image, IN LOADED_IMAGE_PRIVATE_DATA *Image
IN UINTN UserStackBase,
IN UINTN UserStackSize
); );
#endif #endif

View File

@ -1033,30 +1033,6 @@ CoreUnloadAndCloseImage (
CoreFreePool (Image); CoreFreePool (Image);
} }
STATIC
UINTN
EFIAPI
AllocateStack (
IN UINTN Size,
OUT UINTN *Base
)
{
UINTN TopOfStack;
ASSERT (Base != NULL);
ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE));
*Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size));
ASSERT (*Base != 0);
//
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
//
TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT;
TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT);
return TopOfStack;
}
/** /**
Loads an EFI image into memory and returns a handle to the image. Loads an EFI image into memory and returns a handle to the image.
@ -1132,7 +1108,6 @@ CoreLoadImageCommon (
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT8 ImageOrigin; UINT8 ImageOrigin;
EFI_FV_FILE_ATTRIBUTES FileAttributes; EFI_FV_FILE_ATTRIBUTES FileAttributes;
UINTN UserStackBase;
SecurityStatus = EFI_SUCCESS; SecurityStatus = EFI_SUCCESS;
@ -1470,14 +1445,7 @@ CoreLoadImageCommon (
ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage);
if ((gRing3Data != NULL) && Image->IsUserImage) { if ((gRing3Data != NULL) && Image->IsUserImage) {
Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); Image->UserPageTable = InitializeUserPageTable (Image);
SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER);
Image->UserPageTable = InitializeUserPageTable (
Image,
UserStackBase,
STACK_SIZE
);
} }
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
@ -1742,7 +1710,6 @@ CoreStartImage (
UserDriver->CoreWrapper = NULL; UserDriver->CoreWrapper = NULL;
UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint;
UserDriver->UserPageTable = Image->UserPageTable; UserDriver->UserPageTable = Image->UserPageTable;
UserDriver->UserStackTop = Image->UserStackTop;
UserDriver->NumberOfCalls = 0; UserDriver->NumberOfCalls = 0;
InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link);

View File

@ -547,7 +547,6 @@ CallBootService (
NewDriver->CoreWrapper = CoreArgList[Index + 1]; NewDriver->CoreWrapper = CoreArgList[Index + 1];
NewDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserSpaceDriver = UserArgList[Index + 1];
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->NumberOfCalls = 0; NewDriver->NumberOfCalls = 0;
InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link);

View File

@ -180,9 +180,7 @@ InitializeRing3 (
UINTN UINTN
EFIAPI EFIAPI
InitializeUserPageTable ( InitializeUserPageTable (
IN LOADED_IMAGE_PRIVATE_DATA *Image, IN LOADED_IMAGE_PRIVATE_DATA *Image
IN UINTN UserStackBase,
IN UINTN UserStackSize
) )
{ {
UINTN UserPageTable; UINTN UserPageTable;
@ -198,7 +196,7 @@ InitializeUserPageTable (
MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize);
// //
// Map gRing3Data, gRing3Interfaces, UserStackBase, DxeRing3 // Map gRing3Data, gRing3Interfaces, DxeRing3
// //
gCpu->SetUserMemoryAttributes ( gCpu->SetUserMemoryAttributes (
gCpu, gCpu,
@ -216,14 +214,6 @@ InitializeUserPageTable (
EFI_MEMORY_XP | EFI_MEMORY_USER EFI_MEMORY_XP | EFI_MEMORY_USER
); );
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
UserStackBase,
UserStackSize,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
SectionAddress = mDxeRing3->StartAddress; SectionAddress = mDxeRing3->StartAddress;
for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { for (Index = 0; Index < mDxeRing3->NumSegments; Index++) {
ImageRecordSegment = &mDxeRing3->Segments[Index]; ImageRecordSegment = &mDxeRing3->Segments[Index];

View File

@ -19,6 +19,30 @@ CallRing3 (
IN UINTN UserStackTop IN UINTN UserStackTop
); );
STATIC
UINTN
EFIAPI
AllocateStack (
IN UINTN Size,
OUT UINTN *Base
)
{
UINTN TopOfStack;
ASSERT (Base != NULL);
ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE));
*Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size));
ASSERT (*Base != 0);
//
// Compute the top of the allocated stack. Pre-allocate a UINTN for safety.
//
TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT;
TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT);
return TopOfStack;
}
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GoToRing3 ( GoToRing3 (
@ -28,32 +52,22 @@ GoToRing3 (
... ...
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
RING3_CALL_DATA *Input; RING3_CALL_DATA *Input;
VA_LIST Marker; VA_LIST Marker;
UINTN Index; UINTN Index;
EFI_PHYSICAL_ADDRESS Ring3Pages; UINTN UserStackTop;
UINT32 PagesNumber; UINTN UserStackBase;
if (UserDriver->NumberOfCalls > MAX_CALL) { if (UserDriver->NumberOfCalls > MAX_CALL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase);
UserStackTop -= ALIGN_VALUE (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN), CPU_STACK_ALIGNMENT);
Status = CoreAllocatePages ( Input = (RING3_CALL_DATA *)UserStackTop;
AllocateAnyPages,
EfiRing3MemoryType,
PagesNumber,
&Ring3Pages
);
if (EFI_ERROR (Status)) {
return Status;
}
Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages;
AllowSupervisorAccessToUserMemory ();
Input->NumberOfArguments = Number; Input->NumberOfArguments = Number;
Input->EntryPoint = EntryPoint; Input->EntryPoint = EntryPoint;
@ -62,21 +76,31 @@ GoToRing3 (
Input->Arguments[Index] = VA_ARG (Marker, UINTN); Input->Arguments[Index] = VA_ARG (Marker, UINTN);
} }
VA_END (Marker); VA_END (Marker);
ForbidSupervisorAccessToUserMemory ();
// SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER);
// TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?),
// because UserDriver can be interrupted and interrupt handler may call the same UserDriver again. gCpu->SetUserMemoryAttributes (
// gCpu,
UserDriver->UserPageTable,
UserStackBase,
STACK_SIZE,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
++UserDriver->NumberOfCalls; ++UserDriver->NumberOfCalls;
//
// Reserve space on stack for 4 arguments (X64 NOOPT prerequisite).
//
UserStackTop -= ALIGN_VALUE (8*4, CPU_STACK_ALIGNMENT);
Status = CallRing3 ( Status = CallRing3 (
Input, Input,
UserDriver->UserStackTop UserStackTop
); );
--UserDriver->NumberOfCalls; --UserDriver->NumberOfCalls;
CoreFreePages (Ring3Pages, PagesNumber); CoreFreePages (UserStackBase, EFI_SIZE_TO_PAGES (STACK_SIZE));
return Status; return Status;
} }
@ -763,7 +787,6 @@ CoreFileOpen (
NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
NewDriver->CoreWrapper = NewFile; NewDriver->CoreWrapper = NewFile;
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->NumberOfCalls = 0; NewDriver->NumberOfCalls = 0;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
@ -865,7 +888,6 @@ CoreSimpleFileSystemOpenVolume (
NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER));
NewDriver->CoreWrapper = File; NewDriver->CoreWrapper = File;
NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserPageTable = UserDriver->UserPageTable;
NewDriver->UserStackTop = UserDriver->UserStackTop;
NewDriver->NumberOfCalls = 0; NewDriver->NumberOfCalls = 0;
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();