Ring3: Fixed memory leaks and passed UserArguments to CallBootService

through User stack for ARM, AARCH64.
This commit is contained in:
Mikhail Krichanov 2025-01-27 11:50:49 +03:00
parent 6a38507512
commit d20d45ae9b
5 changed files with 52 additions and 58 deletions

View File

@ -91,7 +91,7 @@
UINT64 FAR; 0x320 // Fault Address Register UINT64 FAR; 0x320 // Fault Address Register
UINT64 Type; 0x328 // Exception Type UINT64 Type; 0x328 // Exception Type
UINT64 TTBR0; 0x330 // User Page Table UINT64 TTBR0; 0x330 // User Page Table
UINT64 Padding;0x338 // Alignment requirement UINT64 SP_EL0; 0x338 // User Stack Pointer
*/ */
GCC_ASM_EXPORT(ExceptionHandlersEnd) GCC_ASM_EXPORT(ExceptionHandlersEnd)
@ -101,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)
#define GP_CONTEXT_SIZE (32 * 8) #define GP_CONTEXT_SIZE (32 * 8)
#define FP_CONTEXT_SIZE (32 * 16) #define FP_CONTEXT_SIZE (32 * 16)
#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) #define SYS_CONTEXT_SIZE ( 8 * 8) // 8 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096) ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)
@ -253,7 +253,8 @@ ASM_PFX(CommonExceptionEntry):
1:mrs x2, ttbr0_el1 1:mrs x2, ttbr0_el1
b 3f b 3f
2:mrs x2, ttbr0_el2 2:mrs x2, ttbr0_el2
3:stp x2, xzr, [x28, #0x30] 3:mrs x3, sp_el0
stp x2, x3, [x28, #0x30]
// Push FP regs to Stack. // Push FP regs to Stack.
stp q0, q1, [x28, #-FP_CONTEXT_SIZE]! stp q0, q1, [x28, #-FP_CONTEXT_SIZE]!

View File

@ -30,34 +30,32 @@ SysCallBootService (
IN EFI_SYSTEM_CONTEXT Context IN EFI_SYSTEM_CONTEXT Context
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical; UINTN *UserArguments;
ArmEnableInterrupts (); ArmEnableInterrupts ();
Status = CoreAllocatePages ( UserArguments = (UINTN *)(Context.SystemContextAArch64->SP_EL0 - 7 * sizeof (UINTN));
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)),
&Physical
);
if (EFI_ERROR (Status)) {
return Status;
}
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X1), 7 * sizeof (UINTN)); //
// First 6 arguments are passed through X2-X7 and copied to Core stack,
// all the others are on User stack.
//
CopyMem (
(VOID *)UserArguments,
(VOID *)&(Context.SystemContextAArch64->X1),
7 * sizeof (UINTN)
);
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
Status = CallBootService ( Status = CallBootService (
Context.SystemContextAArch64->X0, Context.SystemContextAArch64->X0,
Context.SystemContextAArch64->X1, Context.SystemContextAArch64->X1,
(UINTN *)Physical, UserArguments,
Context.SystemContextAArch64->SP Context.SystemContextAArch64->SP
); );
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)));
ArmDisableInterrupts (); ArmDisableInterrupts ();
return Status; return Status;

View File

@ -29,10 +29,10 @@ SysCallBootService (
IN EFI_SYSTEM_CONTEXT Context IN EFI_SYSTEM_CONTEXT Context
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical; UINT8 Type;
UINT8 Type; UINT8 NumberOfArguments;
UINT8 NumberOfArguments; UINTN *UserArguments;
ArmEnableInterrupts (); ArmEnableInterrupts ();
@ -47,16 +47,6 @@ SysCallBootService (
++NumberOfArguments; ++NumberOfArguments;
} }
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)),
&Physical
);
if (EFI_ERROR (Status)) {
return Status;
}
AllowSupervisorAccessToUserMemory (); AllowSupervisorAccessToUserMemory ();
if (Type == SysCallFreePages) { if (Type == SysCallFreePages) {
// //
@ -64,41 +54,34 @@ SysCallBootService (
// [SP] == Memory // [SP] == Memory
// Memory is passed as 2 words on stack and aligned on 8 bytes. // Memory is passed as 2 words on stack and aligned on 8 bytes.
// //
CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 2 * sizeof (UINTN)); UserArguments = (UINTN *)(Context.SystemContextArm->SP - 2 * sizeof (UINTN));
CopyMem ( CopyMem (
(VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)UserArguments,
(VOID *)Context.SystemContextArm->SP, (VOID *)&(Context.SystemContextArm->R1),
2 * sizeof (UINTN) 2 * sizeof (UINTN)
); );
} else { } else {
// //
// First 2 arguments are passed through R2-R3 and copied to SysCall Stack. // First 2 arguments are passed through R2-R3 and copied to Core stack,
// all the others are on User stack.
// //
CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 3 * sizeof (UINTN)); UserArguments = (UINTN *)(Context.SystemContextArm->SP - 3 * sizeof (UINTN));
if (NumberOfArguments > 2) { CopyMem (
// (VOID *)UserArguments,
// All remaining arguments are on User Stack. (VOID *)&(Context.SystemContextArm->R1),
// 3 * sizeof (UINTN)
CopyMem ( );
(VOID *)((UINTN)Physical + 3 * sizeof (UINTN)),
(VOID *)Context.SystemContextArm->SP,
(NumberOfArguments - 2) * sizeof (UINTN)
);
}
} }
ForbidSupervisorAccessToUserMemory (); ForbidSupervisorAccessToUserMemory ();
Status = CallBootService ( Status = CallBootService (
Type, Type,
NumberOfArguments, NumberOfArguments,
(UINTN *)(UINTN)Physical, UserArguments,
Context.SystemContextArm->SP_EL1 Context.SystemContextArm->SP_EL1
); );
//
// TODO: Fix memory leak for ReturnToCore().
//
CoreFreePages (Physical, EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)));
ArmDisableInterrupts (); ArmDisableInterrupts ();

View File

@ -396,7 +396,15 @@ CallBootService (
switch (Type) { switch (Type) {
case SysCallReturnToCore: case SysCallReturnToCore:
ReturnToCore (Arguments[1], ReturnSP); //
// Argument 1: EFI_STATUS Status
// Argument 2: UINTN ReturnSP
//
Status = (EFI_STATUS)Arguments[1];
FreePool (Arguments);
ReturnToCore (Status, ReturnSP);
break; break;
case SysCallLocateProtocol: case SysCallLocateProtocol:
// //
@ -1510,5 +1518,6 @@ CallBootService (
break; break;
} }
FreePool (Arguments);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }

View File

@ -594,11 +594,14 @@ typedef struct {
UINT64 V30[2]; UINT64 V30[2];
UINT64 V31[2]; UINT64 V31[2];
UINT64 ELR; // Exception Link Register UINT64 ELR; // Exception Link Register
UINT64 SPSR; // Saved Processor Status Register UINT64 SPSR; // Saved Processor Status Register
UINT64 FPSR; // Floating Point Status Register UINT64 FPSR; // Floating Point Status Register
UINT64 ESR; // Exception syndrome register UINT64 ESR; // Exception syndrome register
UINT64 FAR; // Fault Address Register UINT64 FAR; // Fault Address Register
UINT64 Type; // Exception Type
UINT64 TTBR0; // User Page Table
UINT64 SP_EL0; // User Stack Pointer
} EFI_SYSTEM_CONTEXT_AARCH64; } EFI_SYSTEM_CONTEXT_AARCH64;
/// ///