summaryrefslogtreecommitdiffstats
path: root/MdePkg
diff options
context:
space:
mode:
authorTaylor Beebe <taylor.d.beebe@gmail.com>2024-08-27 14:34:35 -0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-09-13 03:58:46 +0000
commit5000568969995293b529f49ea43726e2d0a9dcab (patch)
tree846b74d6008791b58f9f7acd99d8b0cd38f407f2 /MdePkg
parentac43bbacdef18a6fea6d978e096326ec0805885d (diff)
downloadedk2-5000568969995293b529f49ea43726e2d0a9dcab.tar.gz
edk2-5000568969995293b529f49ea43726e2d0a9dcab.tar.bz2
edk2-5000568969995293b529f49ea43726e2d0a9dcab.zip
MdePkg: Create Stack Check Lib
StackCheckLib contains the required functionality for initializing the stack cookie value, checking the value, and triggering an interrupt when a mismatch occurs. The stack cookie is a random value placed on the stack between the stack variables and the return address so that continuously writing past the stack variables will cause the stack cookie to be overwritten. Before the function returns, the stack cookie value will be checked and if there is a mismatch then StackCheckLib handles the failure. Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack check code is written in assembly within this library. GCC and Clang compilers have built-in support for stack cookie checking, so this library only handles failures. Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Diffstat (limited to 'MdePkg')
-rw-r--r--MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S21
-rw-r--r--MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm25
-rw-r--r--MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S21
-rw-r--r--MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm25
-rw-r--r--MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm43
-rw-r--r--MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm23
-rw-r--r--MdePkg/Library/StackCheckLib/Readme.md126
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c38
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c40
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf58
-rw-r--r--MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm43
-rw-r--r--MdePkg/MdePkg.dsc1
12 files changed, 464 insertions, 0 deletions
diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S
new file mode 100644
index 0000000000..bce13643e3
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+// AArch64/StackCookieInterrupt.S
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//------------------------------------------------------------------------------
+
+ .text
+
+//------------------------------------------------------------------------------
+// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+//
+// VOID
+// TriggerStackCookieInterrupt (
+// VOID
+// );
+//------------------------------------------------------------------------------
+.global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ svc FixedPcdGet8 (PcdStackCookieExceptionVector)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm
new file mode 100644
index 0000000000..ff5ee35acc
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+; AArch64/StackCookieInterrupt.asm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ EXPORT TriggerStackCookieInterrupt
+
+ AREA |.text|, CODE, READONLY
+
+;------------------------------------------------------------------------------
+; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+TriggerStackCookieInterrupt PROC
+ SVC FixedPcdGet8 (PcdStackCookieExceptionVector)
+ RET
+TriggerStackCookieInterrupt ENDP
+
+ END
diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S
new file mode 100644
index 0000000000..1f10bb8aea
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+// Arm/StackCookieInterrupt.S
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//------------------------------------------------------------------------------
+
+ .text
+
+//------------------------------------------------------------------------------
+// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+//
+// VOID
+// TriggerStackCookieInterrupt (
+// VOID
+// );
+//------------------------------------------------------------------------------
+.global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ swi FixedPcdGet8 (PcdStackCookieExceptionVector)
+ bx lr
diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm
new file mode 100644
index 0000000000..f1b1e53943
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+; Arm/StackCookieInterrupt.asm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ EXPORT TriggerStackCookieInterrupt
+
+ AREA |.text|, CODE, READONLY
+
+;------------------------------------------------------------------------------
+; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+TriggerStackCookieInterrupt PROC
+ SWI FixedPcdGet8 (PcdStackCookieExceptionVector)
+ BX LR
+TriggerStackCookieInterrupt ENDP
+
+ END
diff --git a/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm
new file mode 100644
index 0000000000..a52ee90ad9
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------
+; IA32/CheckCookieMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+extern ASM_PFX(StackCheckFailure)
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(CpuDeadLoop)
+
+; Called when a buffer check fails. This functionality is dependent on MSVC
+; C runtime libraries and so is unsupported in UEFI.
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+; The GS handler is for checking the stack cookie during SEH or
+; EH exceptions and is unsupported in UEFI.
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; EFIAPI
+; __security_check_cookie (
+; IN UINTN CheckValue
+; );
+;------------------------------------------------------------------------------
+global @__security_check_cookie@4
+@__security_check_cookie@4:
+ cmp ecx, [ASM_PFX(__security_cookie)]
+ jne ASM_PFX(StackCheckFailure)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm
new file mode 100644
index 0000000000..83a686ddb3
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm
@@ -0,0 +1,23 @@
+;------------------------------------------------------------------------------
+; IA32/StackCookieInterrupt.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ int FixedPcdGet8 (PcdStackCookieExceptionVector)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md
new file mode 100644
index 0000000000..636cd047f0
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Readme.md
@@ -0,0 +1,126 @@
+# StackCheckLib
+
+## Table of Contents
+
+- [StackCheckLib](#stackchecklib)
+ - [Table of Contents](#table-of-contents)
+ - [Introduction and Library Instances](#introduction-and-library-instances)
+ - [StackCheckLibStaticInit](#stackchecklibstaticinit)
+ - [StackCheckLibDynamicInit](#stackchecklibdynamicinit)
+ - [StackCheckLibNull](#stackchecklibnull)
+ - [How Failures are Handled](#how-failures-are-handled)
+ - [Debugging Stack Cookie Check Failures](#debugging-stack-cookie-check-failures)
+ - [Usage](#usage)
+
+## Introduction and Library Instances
+
+`StackCheckLib` contains the required functionality for initializing the stack cookie
+value, checking the value, and triggering an interrupt when a mismatch occurs.
+The stack cookie is a random value placed on the stack between the stack variables
+and the return address so that continuously writing past the stack variables will
+cause the stack cookie to be overwritten. Before the function returns, the stack
+cookie value will be checked and if there is a mismatch then `StackCheckLib` handles
+the failure.
+
+Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack
+check code is written in assembly within this library. GCC and Clang compilers
+have built-in support for stack cookie checking, so this library only handles failures.
+
+### StackCheckLibStaticInit
+
+`StackCheckLibStaticInit` is an instance of `StackCheckLib` which does not update the
+stack cookie value for the module at runtime. It's always preferable to use
+`StackCheckLibDynamicInit` for improved security but there are cases where the stack
+cookie global cannot be written to such as in execute-in-place (XIP) modules and during
+the Cache-as-RAM (CAR) phase of the boot process. The stack cookie value is initialized
+at compile time via updates to the AutoGen process. Each module will define
+`STACK_COOKIE_VALUE` which is used for the module stack cookie value.
+
+### StackCheckLibDynamicInit
+
+This section is future work. The below is the proposed instance.
+
+`StackCheckLibDynamicInit` is an instance of `StackCheckLib` which updates the stack
+cookie value for the module at runtime. This is the preferred method for stack cookie
+initialization as it provides improved security. The stack cookie value is initialized
+at runtime by calling `GetRandomNumber32()` or `GetRandomNumber64()` to generate a random
+value via the platform's random number generator protocol. If the random number generator
+returns an error, then the value will still have the build-time randomized value to fall
+back on.
+
+### StackCheckLibNull
+
+`StackCheckLibNull` is an instance of `StackCheckLib` which does not perform any stack
+cookie checks. This is useful for modules which will fail if stack cookie checks are
+inserted. Of course, this is not recommended for production code.
+
+## How Failures are Handled
+
+When a stack cookie check fails, the `StackCheckLib` library will first call into a hook
+function `StackCheckFailureHook()` which only has a NULL implementation in edk2.
+The NULL implementation will simply print the failure address and return, but a platform
+can implement their own instance of this library which can perform additional actions
+before the system triggers an interrupt.
+
+After `StackCheckFailureHook()` returns, the library will trigger an interrupt with
+PcdStackCookieExceptionVector.
+
+- On IA32 and X64 platforms, PcdStackCookieExceptionVector is used as an index into the
+Interrupt Descriptor Table.
+- On ARM platforms, a software interrupt (`SWI`) is called with the value of
+PcdStackCookieExceptionVector. The value can be retrieved by the handler by reading
+bits [7:0] of the instruction opcode which will allow the handler to determine if the
+interrupt was triggered by the stack cookie check. Reference:
+[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0597/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en)
+- On AARCH64 platforms, a supervisor call (`SVC`) is called with the value
+of PcdStackCookieExceptionVector. This value can similarly be retrieved by the
+handler to determine if the interrupt was triggered by the stack cookie check. Reference:
+[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0602/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en)
+
+## Debugging Stack Cookie Check Failures
+
+Tracking down the origin of stack cookie failures can be difficult. Programmers may attempt
+printf debugging to determine which function has an overflow only to find that the failure
+disappears on the next boot. This curiosity is usually due to the black-box heuristic used
+by compilers to determine where to put stack cookie checks or compiler optimization features
+removing the failing check. The address where the failed stack cookie check occurred will
+be printed using DebugLib. If .map files are available, the address combined with the image
+offset can be used to determine the function which failed.
+
+GNU-based compilers have the `-fstack-protector-all` flag to force stack cookie checks on
+all functions which could create a more consistent environment for debugging assuming an
+earlier failure doesn't mask the targeted one and the flash space can accommodate the
+increased size.
+
+The Visual Studio (MSVC) toolchain has the ability to generate `.cod` files during compilation
+which interleave C and the generated assembly code. These files will contain the stack cookie
+checks and are useful for determining where the checks are placed. To generate these files,
+append `/FAcs` to the build options for each target module. The easiest way to do this is to
+update the tools_def file so the `<TARGET>_<TOOLCHAIN>_<ARCH>_CC_FLAGS` includes `/FAcs`.
+
+## Usage
+
+edk2 updated the tools_def to add `/GS` to VS2022 and VS2019 IA32/X64 builds and
+`-fstack-protector` to GCC builds. This will cause stack cookie references to be inserted
+throughout the code. Every module should have a `StackCheckLib` instances linked to satisfy
+these references. So every module doesn't need to add `StackCheckLib` to the LibraryClasses
+section of the INF file, `StackCheckLib` instances should be linked as NULL in the platform
+DSC fies. The only exception to this is host-based unit tests as they will be compiled with
+the runtime libraries which already contain the stack cookie definitions and will collide
+with `StackCheckLib`.
+
+SEC and PEI_CORE modules should always use `StackCheckLibNull` and pre-memory modules
+should use `StackCheckLibStaticInit`. All other modules should use `StackCheckLibDynamicInit`.
+Below is an **example** of how to link the `StackCheckLib` instances in the platform DSC file
+but it may need customization based on the platform's requirements:
+
+```text
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
+[LibraryClasses.common.PEIM]
+ NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+
+[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+ NULL|MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf
+```
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
new file mode 100644
index 0000000000..4146012b90
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
@@ -0,0 +1,38 @@
+/** @file
+ Provides the required functionality for handling stack
+ cookie check failures in GCC.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/StackCheckFailureHookLib.h>
+
+/**
+ Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector
+**/
+VOID
+TriggerStackCookieInterrupt (
+ VOID
+ );
+
+VOID *__stack_chk_guard = (VOID *)(UINTN)STACK_COOKIE_VALUE;
+
+/**
+ This function gets called when a gcc/clang generated stack cookie fails. This implementation calls into a platform
+ failure hook lib and then triggers the stack cookie interrupt.
+
+**/
+VOID
+__stack_chk_fail (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0)));
+ StackCheckFailureHook (RETURN_ADDRESS (0));
+ TriggerStackCookieInterrupt ();
+}
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
new file mode 100644
index 0000000000..406b2d0116
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
@@ -0,0 +1,40 @@
+/** @file
+ Provides the required functionality for handling stack
+ cookie check failures for MSVC.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/StackCheckFailureHookLib.h>
+
+/**
+ Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector
+**/
+VOID
+TriggerStackCookieInterrupt (
+ VOID
+ );
+
+VOID *__security_cookie = (VOID *)(UINTN)STACK_COOKIE_VALUE;
+
+/**
+ This function gets called when an MSVC generated stack cookie fails. This implementation calls into a platform
+ failure hook lib and then triggers the stack cookie interrupt.
+
+ @param[in] ActualCookieValue The value that was written onto the stack, corrupting the stack cookie.
+
+**/
+VOID
+StackCheckFailure (
+ VOID *ActualCookieValue
+ )
+{
+ DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0)));
+ StackCheckFailureHook (RETURN_ADDRESS (0));
+ TriggerStackCookieInterrupt ();
+}
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
new file mode 100644
index 0000000000..ce8bc11f2b
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
@@ -0,0 +1,58 @@
+## @file
+# Provides the required functionality for checking the stack cookie.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckLibStaticInit
+ FILE_GUID = 2b24dc50-e33d-4c9f-8b62-e826f06e483f
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL
+
+[Sources]
+ StackCheckLibCommonMsvc.c | MSFT
+ StackCheckLibCommonGcc.c | GCC
+
+[Sources.IA32]
+ IA32/CheckCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/CheckCookieMsvc.nasm | MSFT
+
+[Sources.IA32, Sources.X64]
+ IA32/StackCookieInterrupt.nasm
+
+[Sources.ARM]
+ Arm/StackCookieInterrupt.S |GCC
+ Arm/StackCookieInterrupt.asm |MSFT
+
+[Sources.AARCH64]
+ AArch64/StackCookieInterrupt.S |GCC
+ AArch64/StackCookieInterrupt.asm |MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ StackCheckFailureHookLib
+ BaseLib
+ DebugLib
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector
+
+[BuildOptions]
+ # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error
+ # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program
+ # optimization tries to do away with references to this symbol. The solution is to not compile the stack
+ # check libs with /GL
+ MSFT:*_*_*_CC_FLAGS = /GL-
+
+ # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where
+ # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because
+ # the compiler inserts the usage.
+ GCC:*_*_*_CC_FLAGS = -fno-lto
diff --git a/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm
new file mode 100644
index 0000000000..ebc4f75712
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------
+; X64/CheckCookieMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+extern ASM_PFX(StackCheckFailure)
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(CpuDeadLoop)
+
+; Called when a buffer check fails. This functionality is dependent on MSVC
+; C runtime libraries and so is unsupported in UEFI.
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+; The GS handler is for checking the stack cookie during SEH or
+; EH exceptions and is unsupported in UEFI.
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; EFIAPI
+; __security_check_cookie (
+; IN UINTN CheckValue
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(__security_check_cookie)
+ASM_PFX(__security_check_cookie):
+ cmp rcx, [ASM_PFX(__security_cookie)]
+ jne ASM_PFX(StackCheckFailure)
+ ret
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index f410a89a00..92809e4a75 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -141,6 +141,7 @@
MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
#