From 7154ce628f67e0f549696c0eeba30767215bf3d3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 24 Jan 2025 19:32:15 +0300 Subject: [PATCH] CpuExceptionHandlerLib: Saved UserPageTable on stack, used CS saved on stack instead of DS for CPL extraction. --- .../CpuExceptionCommon.c | 8 --- .../Ia32/ExceptionHandlerAsm.nasm | 72 +++++++++++-------- .../X64/ExceptionHandlerAsm.nasm | 54 ++++++++------ 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c index 1599fa8e51..82dc2f3101 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -8,14 +8,6 @@ #include "CpuExceptionCommon.h" -// -// Error code flag indicating whether or not an error code will be -// pushed on the stack if an exception occurs. -// -// 1 means an error code will be pushed, otherwise 0 -// -CONST UINT32 mErrorCodeFlag = 0x20227d00; - // // Define the maximum message length // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 07fef59095..226c7409b5 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -23,7 +23,6 @@ ; ; CommonExceptionHandler() ; -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) @@ -32,11 +31,17 @@ ALIGN 4096 global ASM_PFX(CorePageTable) ASM_PFX(CorePageTable): - resq 1 - -global ASM_PFX(UserPageTable) -ASM_PFX(UserPageTable): - resq 1 + resd 1 + +; +; Error code flag indicating whether or not an error code will be +; pushed on the stack if an exception occurs. +; +; 1 means an error code will be pushed, otherwise 0 +; +global ASM_PFX(mErrorCodeFlag) +ASM_PFX(mErrorCodeFlag): + dd 0x20227d00 ALIGN 4096 Padding: @@ -101,16 +106,6 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - ; Check whether User Space process was interrupted. - mov eax, ds - and eax, 3 - jz NoCr3Switch - mov eax, cr3 - mov [ASM_PFX(UserPageTable)], eax - mov eax, [ASM_PFX(CorePageTable)] - mov cr3, eax - -NoCr3Switch: pop eax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -219,14 +214,30 @@ ErrorCodeAndVectorOnStack: push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + ; Check whether User Space process was interrupted. + push eax + mov eax, [ebp + 4 * 4] ; CS + and eax, 3 + jz NoCr3Switch + mov eax, cr3 + push eax ; UserPageTable + mov eax, [ASM_PFX(CorePageTable)] + mov cr3, eax + mov eax, [esp + 4] ; eax + sub esp, 8 + push eax + +NoCr3Switch: + pop eax + ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; push eax push ecx push edx push ebx lea ecx, [ebp + 6 * 4] - ; Check whether Ring0 process was interrupted. - mov eax, ds + ; Check whether User Space process was interrupted. + mov eax, [ebp + 4 * 4] ; CS and eax, 3 jz sameCPL_0 mov ecx, [ecx] @@ -238,8 +249,8 @@ sameCPL_0: ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; mov eax, ss - ; Check whether Ring0 process was interrupted. - mov ecx, ds + ; Check whether User Space process was interrupted. + mov ecx, [ebp + 4 * 4] ; CS and ecx, 3 jz sameCPL_1 movzx eax, word [ebp + 7 * 4] @@ -412,8 +423,8 @@ sameCPL_1: pop es pop ds pop dword [ebp + 4 * 4] - ; Check whether Ring0 process was interrupted. - mov ecx, ds + ; Check whether User Space process was interrupted. + mov ecx, [ebp + 4 * 4] ; CS and ecx, 3 jz sameCPL_2 pop dword [ebp + 7 * 4] @@ -432,12 +443,12 @@ continue: pop ecx pop eax - ; Check whether Ring3 process was interrupted. - push ecx - mov ecx, ds - and ecx, 3 + ; Check whether User Space process was interrupted. + push eax + mov eax, [ebp + 4 * 4] ; CS + and eax, 3 + pop eax jnz ReturnToRing3 - pop ecx pop dword [ebp - 8] pop dword [ebp - 4] @@ -467,9 +478,10 @@ DoReturn: DoIret: iretd ReturnToRing3: - mov ecx, [ASM_PFX(UserPageTable)] - mov cr3, ecx - pop ecx + add esp, 8 + pop eax ; UserPageTable + mov cr3, eax + pop eax mov esp, ebp pop ebp add esp, 8 diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 278ff4f592..78722bd5a9 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -48,7 +48,6 @@ endstruc %define VC_EXCEPTION 29 -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) @@ -59,9 +58,15 @@ global ASM_PFX(CorePageTable) ASM_PFX(CorePageTable): resq 1 -global ASM_PFX(UserPageTable) -ASM_PFX(UserPageTable): - resq 1 +; +; Error code flag indicating whether or not an error code will be +; pushed on the stack if an exception occurs. +; +; 1 means an error code will be pushed, otherwise 0 +; +global ASM_PFX(mErrorCodeFlag) +ASM_PFX(mErrorCodeFlag): + dd 0x20227d00 ALIGN 4096 Padding: @@ -136,16 +141,6 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - ; Check whether User Space process was interrupted. - mov rax, ds - and rax, 3 - jz NoCr3Switch - mov rax, cr3 - mov [ASM_PFX(UserPageTable)], rax - mov rax, [ASM_PFX(CorePageTable)] - mov cr3, rax - -NoCr3Switch: pop rax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -199,6 +194,21 @@ HasErrorCode: ; is 16-byte aligned ; + ; Check whether User Space process was interrupted. + push rax + mov rax, [rbp + 8*4] ; CS + and rax, 3 + jz NoCr3Switch + mov rax, cr3 + push rax ; UserPageTable + mov rax, [ASM_PFX(CorePageTable)] + mov cr3, rax + mov rax, [rsp + 8] ; rax + push rax + +NoCr3Switch: + pop rax + ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; push r15 @@ -457,12 +467,12 @@ CetDone: pop r14 pop r15 - ; Check whether Ring3 process was interrupted. - push rcx - mov rcx, ds - and rcx, 3 + ; Check whether User Space process was interrupted. + push rax + mov rax, [rbp + 8*4] ; CS + and rax, 3 + pop rax jnz ReturnToRing3 - pop rcx mov rsp, rbp pop rbp @@ -491,9 +501,9 @@ DoReturn: DoIret: iretq ReturnToRing3: - mov rcx, [ASM_PFX(UserPageTable)] - mov cr3, rcx - pop rcx + pop rax ; UserPageTable + mov cr3, rax + pop rax mov rsp, rbp pop rbp add rsp, 16